Index: rice-framework/krad-it/src/test/java/org/kuali/rice/krad/uif/RichMessageTest.java
===================================================================
--- rice-framework/krad-it/src/test/java/org/kuali/rice/krad/uif/RichMessageTest.java (revision 41915)
+++ rice-framework/krad-it/src/test/java/org/kuali/rice/krad/uif/RichMessageTest.java (working copy)
@@ -572,9 +572,9 @@
* @param component
*/
private void performSimulatedLifecycle(Component component) {
- component.performInitialization(view, model);
- component.performApplyModel(view, model, view);
- component.performFinalize(view, model, view);
+ component.performInitialization(model);
+ component.performApplyModel(model, view);
+ component.performFinalize(model, view);
}
/**
Index: rice-framework/krad-sampleapp/src/main/java/org/kuali/rice/krad/demo/uif/components/ComponentExhibit.java
===================================================================
--- rice-framework/krad-sampleapp/src/main/java/org/kuali/rice/krad/demo/uif/components/ComponentExhibit.java (revision 41915)
+++ rice-framework/krad-sampleapp/src/main/java/org/kuali/rice/krad/demo/uif/components/ComponentExhibit.java (working copy)
@@ -20,6 +20,7 @@
import org.kuali.rice.krad.uif.container.TabGroup;
import org.kuali.rice.krad.uif.element.ContentElementBase;
import org.kuali.rice.krad.uif.field.FieldGroup;
+import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
import org.kuali.rice.krad.uif.view.View;
import org.kuali.rice.krad.uif.widget.SyntaxHighlighter;
@@ -50,13 +51,13 @@
* @see Component#performInitialization(org.kuali.rice.krad.uif.view.View, Object)
*/
@Override
- public void performInitialization(View view, Object model) {
+ public void performInitialization(Object model) {
//Setup tabGroup
List tabItems = new ArrayList();
tabItems.addAll(tabGroup.getItems());
tabItems.addAll(demoGroups);
tabGroup.setItems(tabItems);
- view.assignComponentIds(tabGroup);
+ ViewLifecycle.getActiveLifecycle().getView().assignComponentIds(tabGroup);
//source code viewer setup
if(demoSourceCode != null && !demoSourceCode.isEmpty()){
Index: rice-framework/krad-sampleapp/src/main/java/org/kuali/rice/krad/demo/uif/components/ComponentLibraryView.java
===================================================================
--- rice-framework/krad-sampleapp/src/main/java/org/kuali/rice/krad/demo/uif/components/ComponentLibraryView.java (revision 41915)
+++ rice-framework/krad-sampleapp/src/main/java/org/kuali/rice/krad/demo/uif/components/ComponentLibraryView.java (working copy)
@@ -15,9 +15,21 @@
*/
package org.kuali.rice.krad.demo.uif.components;
+import java.io.File;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.LineIterator;
-import org.kuali.rice.core.api.util.AbstractKeyValue;
import org.kuali.rice.core.api.util.ConcreteKeyValue;
import org.kuali.rice.core.api.util.KeyValue;
import org.kuali.rice.krad.datadictionary.parse.BeanTag;
@@ -32,25 +44,11 @@
import org.kuali.rice.krad.uif.element.Header;
import org.kuali.rice.krad.uif.element.Message;
import org.kuali.rice.krad.uif.field.InputField;
+import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
import org.kuali.rice.krad.uif.util.ComponentFactory;
import org.kuali.rice.krad.uif.view.FormView;
-import org.kuali.rice.krad.uif.view.View;
import org.springframework.util.StringUtils;
-import javax.swing.text.StyleContext;
-import java.io.File;
-import java.lang.reflect.Method;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
/**
* View for the ComponentLibrary demo examples of Uif Components
*
@@ -87,8 +85,8 @@
* @see Component#performInitialization(org.kuali.rice.krad.uif.view.View, Object)
*/
@Override
- public void performInitialization(View view, Object model) {
- super.performInitialization(view, model);
+ public void performInitialization(Object model) {
+ super.performInitialization(model);
MessageService messageService = KRADServiceLocatorWeb.getMessageService();
@@ -151,7 +149,7 @@
detailsItems.addAll(detailsGroup.getItems());
detailsItems.add(tabGroup);
detailsGroup.setItems(detailsItems);
- view.assignComponentIds(detailsGroup);
+ ViewLifecycle.getActiveLifecycle().getView().assignComponentIds(detailsGroup);
//exhibit setup
List sourceCode = new ArrayList();
@@ -166,7 +164,7 @@
if (this.getExampleSize() != null &&
(this.getExampleSize().equals(ExampleSize.LARGE) || this.getExampleSize().equals(ExampleSize.XLARGE))) {
exhibit.getTabGroup().addStyleClass("demo-noTabs");
- Group headerRightGroup = view.getPage().getHeader().getRightGroup();
+ Group headerRightGroup = ViewLifecycle.getActiveLifecycle().getView().getPage().getHeader().getRightGroup();
for (Component item : headerRightGroup.getItems()) {
if (item instanceof InputField && ((InputField) item).getControl() instanceof MultiValueControl && item
.getId().equals(this.getLargeExampleFieldId())) {
Index: rice-framework/krad-service-impl/src/main/java/org/kuali/rice/krad/uif/service/impl/ViewServiceImpl.java
===================================================================
--- rice-framework/krad-service-impl/src/main/java/org/kuali/rice/krad/uif/service/impl/ViewServiceImpl.java (revision 41915)
+++ rice-framework/krad-service-impl/src/main/java/org/kuali/rice/krad/uif/service/impl/ViewServiceImpl.java (working copy)
@@ -15,10 +15,12 @@
*/
package org.kuali.rice.krad.uif.service.impl;
+import java.util.List;
+import java.util.Map;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.Logger;
-import org.apache.log4j.Priority;
import org.kuali.rice.core.api.CoreApiServiceLocator;
import org.kuali.rice.krad.datadictionary.validator.ValidationController;
import org.kuali.rice.krad.service.DataDictionaryService;
@@ -26,15 +28,11 @@
import org.kuali.rice.krad.uif.UifConstants.ViewStatus;
import org.kuali.rice.krad.uif.UifConstants.ViewType;
import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
-import org.kuali.rice.krad.uif.service.ViewHelperService;
import org.kuali.rice.krad.uif.service.ViewService;
import org.kuali.rice.krad.uif.service.ViewTypeService;
import org.kuali.rice.krad.uif.view.View;
import org.kuali.rice.krad.web.form.UifFormBase;
-import java.util.List;
-import java.util.Map;
-
/**
* Implementation of ViewService
*
@@ -57,22 +55,12 @@
/**
* @see org.kuali.rice.krad.uif.service.ViewService#getViewById(java.lang.String)
*/
- public View getViewById(String viewId) {
+ public View getViewById(final String viewId) {
if (LOG.isDebugEnabled()) {
LOG.debug("retrieving view instance for id: " + viewId);
}
-
- View view = dataDictionaryService.getViewById(viewId);
- if (view == null) {
- LOG.warn("View not found for id: " + viewId);
- } else {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Updating view status to CREATED for view: " + view.getId());
- }
- view.setViewStatus(ViewStatus.CREATED);
- }
-
- return view;
+
+ return dataDictionaryService.getViewById(viewId);
}
/**
@@ -94,9 +82,6 @@
View view = dataDictionaryService.getViewByTypeIndex(viewType, typeParameters);
if (view == null) {
LOG.warn("View not found for type: " + viewType);
- } else {
- LOG.debug("Updating view status to CREATED for view: " + view.getId());
- view.setViewStatus(ViewStatus.CREATED);
}
return view;
@@ -118,54 +103,30 @@
}
/**
+ * TODO: Consider moving this method to ViewLifecycle
* @see org.kuali.rice.krad.uif.service.ViewService#buildView(org.kuali.rice.krad.uif.view.View, java.lang.Object,
* java.util.Map)
*/
- public void buildView(View view, Object model, Map parameters) {
- // get the configured helper service for the view
- ViewHelperService helperService = view.getViewHelperService();
-
- // populate view from request parameters
- helperService.populateViewFromRequestParameters(view, parameters);
-
- // backup view request parameters on form for recreating lost views (session timeout)
- ((UifFormBase) model).setViewRequestParameters(view.getViewRequestParameters());
-
- // run view lifecycle
- performViewLifecycle(view, model, parameters);
-
- // Validation of the page's beans
- if (CoreApiServiceLocator.getKualiConfigurationService().getPropertyValueAsBoolean(
- UifConstants.VALIDATE_VIEWS_ONBUILD)) {
- ValidationController validator = new ValidationController(true, true, true, true, false);
- Log tempLogger = LogFactory.getLog(ViewServiceImpl.class);
- validator.validate(view, tempLogger, false);
- }
- }
-
- /**
- * Initializes a newly created View
instance. Each component of the tree is invoked
- * to perform setup based on its configuration. In addition helper service methods are invoked to
- * perform custom initialization
- *
- * @param view - view instance to initialize
- * @param model - object instance containing the view data
- * @param parameters - Map of key values pairs that provide configuration for the View
, this
- * is generally comes from the request and can be the request parameter Map itself. Any parameters
- * not valid for the View will be filtered out
- */
- protected void performViewLifecycle(final View view, final Object model, final Map parameters) {
- // get the configured helper service for the view
- final ViewHelperService helperService = view.getViewHelperService();
-
- helperService.encapsulateViewLifecycle(new Runnable(){
+ public View buildView(View view, final Object model, final Map parameters) {
+ View builtView = ViewLifecycle.encapsulateLifecycle(view, new Runnable(){
@Override
public void run() {
+ ViewLifecycle viewLifecycle = ViewLifecycle.getActiveLifecycle();
+ View view = viewLifecycle.getView();
+
+ // populate view from request parameters
+ viewLifecycle.populateViewFromRequestParameters(parameters);
+
+ // backup view request parameters on form for recreating lost
+ // views (session timeout)
+ ((UifFormBase) model).setViewRequestParameters(view
+ .getViewRequestParameters());
+
// invoke initialize phase on the views helper service
- if (LOG.isEnabledFor(Priority.INFO)) {
+ if (LOG.isInfoEnabled()) {
LOG.info("performing initialize phase for view: " + view.getId());
}
- helperService.performInitialization(view, model);
+ viewLifecycle.performInitialization(model);
// do indexing
if (LOG.isDebugEnabled()) {
@@ -180,25 +141,25 @@
view.setViewStatus(ViewStatus.INITIALIZED);
// Apply Model Phase
- if (LOG.isEnabledFor(Priority.INFO)) {
+ if (LOG.isInfoEnabled()) {
LOG.info("performing apply model phase for view: " + view.getId());
}
- helperService.performApplyModel(view, model);
+ viewLifecycle.performApplyModel(model);
// do indexing
- if (LOG.isEnabledFor(Priority.INFO)) {
+ if (LOG.isInfoEnabled()) {
LOG.info("reindexing after apply model for view: " + view.getId());
}
view.index();
// Finalize Phase
- if (LOG.isEnabledFor(Priority.INFO)) {
+ if (LOG.isInfoEnabled()) {
LOG.info("performing finalize phase for view: " + view.getId());
}
- helperService.performFinalize(view, model);
+ viewLifecycle.performFinalize(model);
// do indexing
- if (LOG.isEnabledFor(Priority.INFO)) {
+ if (LOG.isInfoEnabled()) {
LOG.info("processing final indexing for view: " + view.getId());
}
view.index();
@@ -208,7 +169,17 @@
LOG.debug("Updating view status to FINAL for view: " + view.getId());
}
view.setViewStatus(ViewStatus.FINAL);
- }});
+ }}).getView();
+
+ // Validation of the page's beans
+ if (CoreApiServiceLocator.getKualiConfigurationService().getPropertyValueAsBoolean(
+ UifConstants.VALIDATE_VIEWS_ONBUILD)) {
+ ValidationController validator = new ValidationController(true, true, true, true, false);
+ Log tempLogger = LogFactory.getLog(ViewServiceImpl.class);
+ validator.validate(builtView, tempLogger, false);
+ }
+
+ return builtView;
}
public ViewTypeService getViewTypeService(UifConstants.ViewType viewType) {
Index: rice-framework/krad-web-framework/src/main/java/org/kuali/rice/krad/datadictionary/DataDictionary.java
===================================================================
--- rice-framework/krad-web-framework/src/main/java/org/kuali/rice/krad/datadictionary/DataDictionary.java (revision 41915)
+++ rice-framework/krad-web-framework/src/main/java/org/kuali/rice/krad/datadictionary/DataDictionary.java (working copy)
@@ -26,6 +26,7 @@
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
+import java.util.concurrent.Callable;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.collections.ListUtils;
@@ -48,6 +49,7 @@
import org.kuali.rice.krad.service.LegacyDataAdapter;
import org.kuali.rice.krad.uif.UifConstants;
import org.kuali.rice.krad.uif.UifConstants.ViewType;
+import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
import org.kuali.rice.krad.uif.util.ComponentBeanPostProcessor;
import org.kuali.rice.krad.uif.util.ComponentFactory;
import org.kuali.rice.krad.uif.util.UifBeanFactoryPostProcessor;
@@ -194,56 +196,62 @@
* @param allowConcurrentValidation - indicates whether the indexing should occur on a different thread
* or the same thread
*/
- public void performDictionaryPostProcessing(boolean allowConcurrentValidation) {
- LOG.info( "Starting Data Dictionary Post Processing");
- timer.start("Spring Post Processing");
- PropertyPlaceholderConfigurer propertyPlaceholderConfigurer = new PropertyPlaceholderConfigurer();
- propertyPlaceholderConfigurer.setProperties(ConfigContext.getCurrentContextConfig().getProperties());
- propertyPlaceholderConfigurer.postProcessBeanFactory(ddBeans);
-
- DictionaryBeanFactoryPostProcessor dictionaryBeanPostProcessor = new DictionaryBeanFactoryPostProcessor(this,
- ddBeans);
- dictionaryBeanPostProcessor.postProcessBeanFactory();
- timer.stop();
- timer.start("UIF Post Processing");
- // post processes UIF beans for pulling out expressions within property values
- UifBeanFactoryPostProcessor factoryPostProcessor = new UifBeanFactoryPostProcessor();
- factoryPostProcessor.postProcessBeanFactory(ddBeans);
- timer.stop();
-
- timer.start("Instantiating DD Beans");
- ddBeans.preInstantiateSingletons();
- timer.stop();
-
- // Allow the DD to perform final post processing in a controlled order
- // Unlike the Spring post processor, we will only call for these operations on the
- // "top-level" beans and have them call post processing actions on embedded DD objects, if needed
- timer.start("DD Post Processing");
- for (DataObjectEntry entry : ddBeans.getBeansOfType(DataObjectEntry.class).values()) {
- entry.dataDictionaryPostProcessing();
- }
- for (DocumentEntry entry : ddBeans.getBeansOfType(DocumentEntry.class).values()) {
- entry.dataDictionaryPostProcessing();
- }
- timer.stop();
-
- timer.start("Data Dictionary Indexing");
- ddIndex.run();
- timer.stop();
-
- // The UIF defaulting must be done before the UIF indexing but after
- // the main DD data object indexing
- timer.start("UIF Defaulting");
- // Check if there are inquiry definitions for data objects
- generateMissingInquiryDefinitions();
- // Check if there are lookup definitions for data objects
- generateMissingLookupDefinitions();
- timer.stop();
+ public void performDictionaryPostProcessing(final boolean allowConcurrentValidation) {
+ ViewLifecycle.encapsulateInitialization(new Callable() {
+ @Override
+ public Void call() throws Exception {
+ LOG.info("Starting Data Dictionary Post Processing");
+ timer.start("Spring Post Processing");
+ PropertyPlaceholderConfigurer propertyPlaceholderConfigurer = new PropertyPlaceholderConfigurer();
+ propertyPlaceholderConfigurer.setProperties(ConfigContext.getCurrentContextConfig().getProperties());
+ propertyPlaceholderConfigurer.postProcessBeanFactory(ddBeans);
+
+ DictionaryBeanFactoryPostProcessor dictionaryBeanPostProcessor =
+ new DictionaryBeanFactoryPostProcessor(DataDictionary.this, ddBeans);
+ dictionaryBeanPostProcessor.postProcessBeanFactory();
+ timer.stop();
+ timer.start("UIF Post Processing");
+ // post processes UIF beans for pulling out expressions within property values
+ UifBeanFactoryPostProcessor factoryPostProcessor = new UifBeanFactoryPostProcessor();
+ factoryPostProcessor.postProcessBeanFactory(ddBeans);
+ timer.stop();
+
+ timer.start("Instantiating DD Beans");
+ ddBeans.preInstantiateSingletons();
+ timer.stop();
+
+ // Allow the DD to perform final post processing in a controlled order
+ // Unlike the Spring post processor, we will only call for these operations on the
+ // "top-level" beans and have them call post processing actions on embedded DD objects, if needed
+ timer.start("DD Post Processing");
+ for (DataObjectEntry entry : ddBeans.getBeansOfType(DataObjectEntry.class).values()) {
+ entry.dataDictionaryPostProcessing();
+ }
+ for (DocumentEntry entry : ddBeans.getBeansOfType(DocumentEntry.class).values()) {
+ entry.dataDictionaryPostProcessing();
+ }
+ timer.stop();
- timer.start("UIF Indexing");
- uifIndex.run();
- timer.stop();
- LOG.info( "Completed Data Dictionary Post Processing");
+ timer.start("Data Dictionary Indexing");
+ ddIndex.run();
+ timer.stop();
+
+ // The UIF defaulting must be done before the UIF indexing but after
+ // the main DD data object indexing
+ timer.start("UIF Defaulting");
+ // Check if there are inquiry definitions for data objects
+ generateMissingInquiryDefinitions();
+ // Check if there are lookup definitions for data objects
+ generateMissingLookupDefinitions();
+ timer.stop();
+
+ timer.start("UIF Indexing");
+ uifIndex.run();
+ timer.stop();
+ LOG.info("Completed Data Dictionary Post Processing");
+ return null;
+ }
+ });
}
protected void generateMissingInquiryDefinitions() {
@@ -328,42 +336,48 @@
}
}
- public void validateDD(boolean validateEbos) {
- timer.start("Validation");
- DataDictionary.validateEBOs = validateEbos;
-
- Validator.resetErrorReport();
-
- Map doBeans = ddBeans.getBeansOfType(DataObjectEntry.class);
- for (DataObjectEntry entry : doBeans.values()) {
- entry.completeValidation( new ValidationTrace() );
- }
-
- Map docBeans = ddBeans.getBeansOfType(DocumentEntry.class);
- for (DocumentEntry entry : docBeans.values()) {
- entry.completeValidation( new ValidationTrace() );
- }
-
- List errorReports = Validator.getErrorReports();
- if ( errorReports.size() > 0 ) {
- boolean errors = false;
- LOG.error( "***********************************************************");
- LOG.error( "ERRORS OR WARNINGS REPORTED UPON DATA DICTIONARY VALIDATION");
- LOG.error( "***********************************************************");
- for ( ErrorReport err : errorReports ) {
- if ( err.isError() ) {
- LOG.error(err.errorMessage());
- errors = true;
- } else {
- LOG.warn(err.errorMessage());
+ public void validateDD(final boolean validateEbos) {
+ ViewLifecycle.encapsulateInitialization(new Callable() {
+ @Override
+ public Void call() throws Exception {
+ timer.start("Validation");
+ DataDictionary.validateEBOs = validateEbos;
+
+ Validator.resetErrorReport();
+
+ Map doBeans = ddBeans.getBeansOfType(DataObjectEntry.class);
+ for (DataObjectEntry entry : doBeans.values()) {
+ entry.completeValidation(new ValidationTrace());
}
- }
- if ( errors ) {
- throw new DataDictionaryException( "Errors during DD validation, failing validation." );
- }
- }
- timer.stop();
+ Map docBeans = ddBeans.getBeansOfType(DocumentEntry.class);
+ for (DocumentEntry entry : docBeans.values()) {
+ entry.completeValidation(new ValidationTrace());
+ }
+
+ List errorReports = Validator.getErrorReports();
+ if (errorReports.size() > 0) {
+ boolean errors = false;
+ LOG.error("***********************************************************");
+ LOG.error("ERRORS OR WARNINGS REPORTED UPON DATA DICTIONARY VALIDATION");
+ LOG.error("***********************************************************");
+ for (ErrorReport err : errorReports) {
+ if (err.isError()) {
+ LOG.error(err.errorMessage());
+ errors = true;
+ } else {
+ LOG.warn(err.errorMessage());
+ }
+ }
+ if (errors) {
+ throw new DataDictionaryException("Errors during DD validation, failing validation.");
+ }
+ }
+
+ timer.stop();
+ return null;
+ }
+ });
}
public void validateDD() {
@@ -685,7 +699,7 @@
* @param beanName - id or name for the bean definition
* @return Object object instance created or the singleton being maintained
*/
- public Object getDictionaryObject(String beanName) {
+ public Object getDictionaryObject(final String beanName) {
return ddBeans.getBean(beanName);
}
Index: rice-framework/krad-web-framework/src/main/java/org/kuali/rice/krad/datadictionary/uif/UifDictionaryIndex.java
===================================================================
--- rice-framework/krad-web-framework/src/main/java/org/kuali/rice/krad/datadictionary/uif/UifDictionaryIndex.java (revision 41915)
+++ rice-framework/krad-web-framework/src/main/java/org/kuali/rice/krad/datadictionary/uif/UifDictionaryIndex.java (working copy)
@@ -20,6 +20,7 @@
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.concurrent.Callable;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
@@ -29,9 +30,10 @@
import org.kuali.rice.krad.datadictionary.DefaultListableBeanFactory;
import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
import org.kuali.rice.krad.uif.UifConstants;
+import org.kuali.rice.krad.uif.UifConstants.ViewStatus;
import org.kuali.rice.krad.uif.UifConstants.ViewType;
+import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
import org.kuali.rice.krad.uif.service.ViewTypeService;
-import org.kuali.rice.krad.uif.util.ComponentUtils;
import org.kuali.rice.krad.uif.util.ViewModelUtils;
import org.kuali.rice.krad.uif.view.View;
import org.kuali.rice.krad.util.KRADConstants;
@@ -51,7 +53,7 @@
*/
public class UifDictionaryIndex implements Runnable {
private static final Log LOG = LogFactory.getLog(UifDictionaryIndex.class);
-
+
private static final int VIEW_CACHE_SIZE = 1000;
private DefaultListableBeanFactory ddBeans;
@@ -87,19 +89,47 @@
* @return View instance with the given id
* @throws org.kuali.rice.krad.datadictionary.DataDictionaryException if view doesn't exist for id
*/
- public View getViewById(String viewId) {
+ public View getViewById(final String viewId) {
+ View view = getImmutableViewById(viewId);
+
+ if ( LOG.isDebugEnabled() ) {
+ LOG.debug("Pulled view " + viewId + " from Cache. Cloning..." );
+ }
+
+ return ViewLifecycle.getMutableCopy(view);
+ }
+
+ /**
+ * Gets a view instance from the pool or factory but does not replace the view, meant for view readonly
+ * access (not running the lifecycle but just checking configuration)
+ *
+ * @param viewId the unique id for the view
+ * @return View instance with the given id
+ */
+ public View getImmutableViewById(String viewId) {
View cachedView = viewCache.get(viewId);
if ( cachedView == null ) {
if ( LOG.isDebugEnabled() ) {
LOG.debug( "View " + viewId + " not in cache - creating and storing to cache");
}
- String beanName = viewBeanEntriesById.get(viewId);
+ final String beanName = viewBeanEntriesById.get(viewId);
if (StringUtils.isBlank(beanName)) {
throw new DataDictionaryException("Unable to find View with id: " + viewId);
}
- View newView = ddBeans.getBean(beanName, View.class);
+ View newView = ViewLifecycle.encapsulateInitialization(new Callable(){
+ @Override
+ public View call() throws Exception {
+ View view = ddBeans.getBean(beanName, View.class);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Updating view status to CREATED for view: " + view.getId());
+ }
+
+ view.setViewStatus(ViewStatus.CREATED);
+ return view;
+ }});
boolean inDevMode = ConfigContext.getCurrentContextConfig().getBooleanProperty(
KRADConstants.ConfigParameters.KRAD_DEV_MODE);
@@ -108,36 +138,13 @@
synchronized (viewCache) {
viewCache.put(viewId, newView);
}
+ } else if ( LOG.isDebugEnabled() ) {
+ LOG.debug( "DEV MODE - View " + viewId + " will not be cached");
}
-
+
cachedView = newView;
- } else {
- if ( LOG.isDebugEnabled() ) {
- LOG.debug("Pulled view " + viewId + " from Cache. Cloning..." );
- }
}
- View clonedView = ComponentUtils.copy(cachedView);
-
- return clonedView;
- }
-
- /**
- * Gets a view instance from the pool or factory but does not replace the view, meant for view readonly
- * access (not running the lifecycle but just checking configuration)
- *
- * @param viewId the unique id for the view
- * @return View instance with the given id
- */
- public View getImmutableViewById(String viewId) {
- // check for preloaded view
- View cachedView = viewCache.get(viewId);
- // If not already cached, pull and cache as normal
- // This makes the first call to this method more expensive, as it
- // will get a cloned copy instead of the original from the cache
- if ( cachedView == null ) {
- return getViewById(viewId);
- }
return cachedView;
}
Index: rice-framework/krad-web-framework/src/main/java/org/kuali/rice/krad/inquiry/InquirableImpl.java
===================================================================
--- rice-framework/krad-web-framework/src/main/java/org/kuali/rice/krad/inquiry/InquirableImpl.java (revision 41915)
+++ rice-framework/krad-web-framework/src/main/java/org/kuali/rice/krad/inquiry/InquirableImpl.java (working copy)
@@ -328,7 +328,7 @@
}
@Override
- protected DataDictionaryService getDataDictionaryService() {
+ public DataDictionaryService getDataDictionaryService() {
return KRADServiceLocatorWeb.getDataDictionaryService();
}
Index: rice-framework/krad-web-framework/src/main/java/org/kuali/rice/krad/lookup/LookupableImpl.java
===================================================================
--- rice-framework/krad-web-framework/src/main/java/org/kuali/rice/krad/lookup/LookupableImpl.java (revision 41915)
+++ rice-framework/krad-web-framework/src/main/java/org/kuali/rice/krad/lookup/LookupableImpl.java (working copy)
@@ -43,6 +43,7 @@
import org.kuali.rice.krad.uif.element.Action;
import org.kuali.rice.krad.uif.field.InputField;
import org.kuali.rice.krad.uif.field.LookupInputField;
+import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
import org.kuali.rice.krad.uif.service.impl.ViewHelperServiceImpl;
import org.kuali.rice.krad.uif.util.ComponentUtils;
import org.kuali.rice.krad.uif.util.LookupInquiryUtils;
@@ -91,7 +92,9 @@
* java.lang.Object)
*/
@Override
- public void performInitialization(View view, Object model) {
+ public void performCustomViewInitialization(Object model) {
+ View view = ViewLifecycle.getActiveLifecycle().getView();
+
if (!LookupView.class.isAssignableFrom(view.getClass())) {
throw new IllegalArgumentException(
"View class '" + view.getClass() + " is not assignable from the '" + LookupView.class + "'");
@@ -99,8 +102,6 @@
LookupView lookupView = (LookupView) view;
setDataObjectClass(lookupView.getDataObjectClassName());
-
- super.performInitialization(view, model);
}
/**
Index: rice-framework/krad-web-framework/src/main/java/org/kuali/rice/krad/maintenance/MaintainableImpl.java
===================================================================
--- rice-framework/krad-web-framework/src/main/java/org/kuali/rice/krad/maintenance/MaintainableImpl.java (revision 41915)
+++ rice-framework/krad-web-framework/src/main/java/org/kuali/rice/krad/maintenance/MaintainableImpl.java (working copy)
@@ -442,7 +442,7 @@
*
*/
@Override
- protected void processAfterAddLine(View view, CollectionGroup collectionGroup, Object model, Object addLine,
+ public void processAfterAddLine(View view, CollectionGroup collectionGroup, Object model, Object addLine,
boolean isValidLine) {
super.processAfterAddLine(view, collectionGroup, model, addLine, isValidLine);
@@ -489,7 +489,7 @@
* org.kuali.rice.krad.uif.container.CollectionGroup, java.lang.Object, int)
*/
@Override
- protected void processAfterDeleteLine(View view, CollectionGroup collectionGroup, Object model, int lineIndex) {
+ public void processAfterDeleteLine(View view, CollectionGroup collectionGroup, Object model, int lineIndex) {
super.processAfterDeleteLine(view, collectionGroup, model, lineIndex);
// Check for maintenance documents in edit but exclude notes and ad hoc recipients
Index: rice-framework/krad-web-framework/src/main/java/org/kuali/rice/krad/uif/component/Component.java
===================================================================
--- rice-framework/krad-web-framework/src/main/java/org/kuali/rice/krad/uif/component/Component.java (revision 41915)
+++ rice-framework/krad-web-framework/src/main/java/org/kuali/rice/krad/uif/component/Component.java (working copy)
@@ -15,16 +15,16 @@
*/
package org.kuali.rice.krad.uif.component;
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
import org.kuali.rice.krad.datadictionary.uif.UifDictionaryBean;
import org.kuali.rice.krad.datadictionary.validator.ValidationTrace;
import org.kuali.rice.krad.uif.modifier.ComponentModifier;
-import org.kuali.rice.krad.uif.view.View;
+import org.kuali.rice.krad.uif.util.LifecycleElement;
import org.kuali.rice.krad.uif.widget.Tooltip;
-import java.io.Serializable;
-import java.util.List;
-import java.util.Map;
-
/**
* Component defines basic properties and methods that all rendering element implement
*
@@ -52,7 +52,7 @@
* @see org.kuali.rice.krad.uif.field.Field
* @see org.kuali.rice.krad.uif.widget.Widget
*/
-public interface Component extends UifDictionaryBean, Serializable, Ordered, ScriptEventSupport {
+public interface Component extends UifDictionaryBean, LifecycleElement, Serializable, Ordered, ScriptEventSupport {
/**
* The unique id (within a given tree) for the component
@@ -185,12 +185,11 @@
* once per component lifecycle and is invoked within the initialize phase of the view lifecylce.
*
*
- * @param view - view instance in which the component belongs
* @param model - object instance containing the view data
* @see org.kuali.rice.krad.uif.service.ViewHelperService#performInitialization(org.kuali.rice.krad.uif.view.View,
* Object)
*/
- void performInitialization(View view, Object model);
+ void performInitialization(Object model);
/**
* Called after the initialize phase to perform conditional logic based on the model data
@@ -200,11 +199,10 @@
* based on the given data
*
*
- * @param view - view instance to which the component belongs
* @param model - Top level object containing the data (could be the form or a
* top level business object, dto)
*/
- void performApplyModel(View view, Object model, Component parent);
+ void performApplyModel(Object model, Component parent);
/**
* The last phase before the view is rendered
@@ -217,7 +215,7 @@
* @param model - top level object containing the data
* @param parent - parent component
*/
- void performFinalize(View view, Object model, Component parent);
+ void performFinalize(Object model, Component parent);
/**
* List of components that are contained within the component and should be sent through
Index: rice-framework/krad-web-framework/src/main/java/org/kuali/rice/krad/uif/component/ComponentBase.java
===================================================================
--- rice-framework/krad-web-framework/src/main/java/org/kuali/rice/krad/uif/component/ComponentBase.java (revision 41915)
+++ rice-framework/krad-web-framework/src/main/java/org/kuali/rice/krad/uif/component/ComponentBase.java (working copy)
@@ -18,9 +18,9 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import org.apache.commons.lang.StringUtils;
import org.kuali.rice.krad.data.DataObjectUtils;
@@ -31,9 +31,13 @@
import org.kuali.rice.krad.datadictionary.validator.Validator;
import org.kuali.rice.krad.uif.CssConstants;
import org.kuali.rice.krad.uif.control.ControlBase;
+import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
import org.kuali.rice.krad.uif.modifier.ComponentModifier;
import org.kuali.rice.krad.uif.util.CloneUtils;
import org.kuali.rice.krad.uif.util.ExpressionUtils;
+import org.kuali.rice.krad.uif.util.LifecycleAwareList;
+import org.kuali.rice.krad.uif.util.LifecycleAwareMap;
+import org.kuali.rice.krad.uif.util.LifecycleElement;
import org.kuali.rice.krad.uif.util.ProcessLogger;
import org.kuali.rice.krad.uif.util.ScriptUtils;
import org.kuali.rice.krad.uif.view.ExpressionEvaluator;
@@ -54,8 +58,20 @@
*/
@BeanTag(name = "componentBase-bean", parent = "Uif-ComponentBase")
public abstract class ComponentBase extends UifDictionaryBeanBase implements Component {
+
private static final long serialVersionUID = -4449335748129894350L;
+ private static final ThreadLocal TL_INITIALIZING = new ThreadLocal();
+
+ public static boolean isInitializing() {
+ return Boolean.TRUE.equals(TL_INITIALIZING.get());
+ }
+
+ /**
+ * Track mutability status.
+ */
+ private boolean mutable;
+
private String id;
private String baseId;
private String template;
@@ -105,6 +121,7 @@
private String cellWidth;
private String style;
+
private List libraryCssClasses;
private List cssClasses;
private List additionalCssClasses;
@@ -148,15 +165,13 @@
private List componentModifiers;
- private Map templateOptions;
+ protected Map templateOptions;
+
private String templateOptionsJSString;
@ReferenceCopy(newCollectionInstance = true)
private transient Map context;
- @ReferenceCopy
- private transient Map unmodifiableContext;
-
private List propertyReplacers;
private Map dataAttributes;
@@ -182,20 +197,69 @@
disableSessionPersistence = false;
forceSessionPersistence = false;
- // TODO : lazy init
- // DONE: refreshWhenChangedPropertyNames = new ArrayList();
- // DONE: additionalComponentsToRefresh = new ArrayList();
- // DONE: finalizeMethodAdditionalArguments = new ArrayList