001 /**
002 * Copyright 2005-2013 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.kuali.rice.krad.uif.service.impl;
017
018 import java.util.HashMap;
019 import java.util.List;
020 import java.util.Map;
021
022 import org.apache.log4j.Logger;
023 import org.apache.log4j.Priority;
024 import org.kuali.rice.krad.service.DataDictionaryService;
025 import org.kuali.rice.krad.uif.UifConstants;
026 import org.kuali.rice.krad.uif.UifConstants.ViewStatus;
027 import org.kuali.rice.krad.uif.view.View;
028 import org.kuali.rice.krad.uif.service.ViewHelperService;
029 import org.kuali.rice.krad.uif.service.ViewService;
030 import org.kuali.rice.krad.uif.service.ViewTypeService;
031 import org.kuali.rice.krad.uif.UifConstants.ViewType;
032 import org.kuali.rice.krad.web.form.UifFormBase;
033
034 /**
035 * Implementation of <code>ViewService</code>
036 *
037 * <p>
038 * Provides methods for retrieving View instances and carrying out the View
039 * lifecycle methods. Interacts with the configured <code>ViewHelperService</code>
040 * during the view lifecycle
041 * </p>
042 *
043 * @author Kuali Rice Team (rice.collab@kuali.org)
044 */
045 public class ViewServiceImpl implements ViewService {
046 private static final Logger LOG = Logger.getLogger(ViewServiceImpl.class);
047
048 private DataDictionaryService dataDictionaryService;
049
050 // TODO: remove once we can get beans by type from spring
051 private List<ViewTypeService> viewTypeServices;
052
053 /**
054 * @see org.kuali.rice.krad.uif.service.ViewService#getViewById(java.lang.String)
055 */
056 public View getViewById(String viewId) {
057 if (LOG.isDebugEnabled()) {
058 LOG.debug("retrieving view instance for id: " + viewId);
059 }
060
061 View view = dataDictionaryService.getViewById(viewId);
062 if (view == null) {
063 LOG.warn("View not found for id: " + viewId);
064 } else {
065 if (LOG.isDebugEnabled()) {
066 LOG.debug("Updating view status to CREATED for view: " + view.getId());
067 }
068 view.setViewStatus(ViewStatus.CREATED);
069 }
070
071 return view;
072 }
073
074 /**
075 * Retrieves the <code>ViewTypeService</code> for the given view type, then builds up the index based
076 * on the supported view type parameters and queries the dictionary service to retrieve the view
077 * based on its type and index
078 *
079 * @see org.kuali.rice.krad.uif.service.ViewService#getViewByType(org.kuali.rice.krad.uif.UifConstants.ViewType,
080 * java.util.Map<java.lang.String,java.lang.String>)
081 */
082 public View getViewByType(ViewType viewType, Map<String, String> parameters) {
083 ViewTypeService typeService = getViewTypeService(viewType);
084 if (typeService == null) {
085 throw new RuntimeException("Unable to find view type service for view type name: " + viewType);
086 }
087
088 Map<String, String> typeParameters = typeService.getParametersFromRequest(parameters);
089
090 Map<String, String> indexKey = new HashMap<String, String>();
091 for (Map.Entry<String, String> parameter : typeParameters.entrySet()) {
092 indexKey.put(parameter.getKey(), parameter.getValue());
093 }
094
095 View view = dataDictionaryService.getViewByTypeIndex(viewType, indexKey);
096 if (view == null) {
097 LOG.warn("View not found for type: " + viewType);
098 } else {
099 LOG.debug("Updating view status to CREATED for view: " + view.getId());
100 view.setViewStatus(ViewStatus.CREATED);
101 }
102
103 return view;
104 }
105
106 /**
107 * @see org.kuali.rice.krad.uif.service.ViewService#buildView(org.kuali.rice.krad.uif.view.View, java.lang.Object,
108 * java.util.Map<java.lang.String,java.lang.String>)
109 */
110 public void buildView(View view, Object model, Map<String, String> parameters) {
111 // get the configured helper service for the view
112 ViewHelperService helperService = view.getViewHelperService();
113
114 // populate view from request parameters
115 helperService.populateViewFromRequestParameters(view, parameters);
116
117 // backup view request parameters on form for recreating lost views (session timeout)
118 ((UifFormBase) model).setViewRequestParameters(view.getViewRequestParameters());
119
120 // run view lifecycle
121 performViewLifecycle(view, model, parameters);
122 }
123
124 /**
125 * Initializes a newly created <code>View</code> instance. Each component of the tree is invoked
126 * to perform setup based on its configuration. In addition helper service methods are invoked to
127 * perform custom initialization
128 *
129 * @param view - view instance to initialize
130 * @param model - object instance containing the view data
131 * @param parameters - Map of key values pairs that provide configuration for the <code>View</code>, this
132 * is generally comes from the request and can be the request parameter Map itself. Any parameters
133 * not valid for the View will be filtered out
134 */
135 protected void performViewLifecycle(View view, Object model, Map<String, String> parameters) {
136 // get the configured helper service for the view
137 ViewHelperService helperService = view.getViewHelperService();
138
139 // invoke initialize phase on the views helper service
140 // Heavily called method showed up on profile as a hotspot. Putting log statements in checks cuts execution time by ~75%
141 if (LOG.isEnabledFor(Priority.INFO)) {
142 LOG.info("performing initialize phase for view: " + view.getId());
143 }
144 helperService.performInitialization(view, model);
145
146 // do indexing
147 if (LOG.isDebugEnabled()) {
148 LOG.debug("processing indexing for view: " + view.getId());
149 }
150 view.index();
151
152 // update status on view
153 if (LOG.isDebugEnabled()) {
154 LOG.debug("Updating view status to INITIALIZED for view: " + view.getId());
155 }
156 view.setViewStatus(ViewStatus.INITIALIZED);
157
158 // Apply Model Phase
159 if (LOG.isEnabledFor(Priority.INFO)) {
160 LOG.info("performing apply model phase for view: " + view.getId());
161 }
162 helperService.performApplyModel(view, model);
163
164 // do indexing
165 if (LOG.isEnabledFor(Priority.INFO)) {
166 LOG.info("reindexing after apply model for view: " + view.getId());
167 }
168 view.index();
169
170 // Finalize Phase
171 if (LOG.isEnabledFor(Priority.INFO)) {
172 LOG.info("performing finalize phase for view: " + view.getId());
173 }
174 helperService.performFinalize(view, model);
175
176 // do indexing
177 if (LOG.isEnabledFor(Priority.INFO)) {
178 LOG.info("processing final indexing for view: " + view.getId());
179 }
180 view.index();
181
182 // update status on view
183 if (LOG.isDebugEnabled()) {
184 LOG.debug("Updating view status to FINAL for view: " + view.getId());
185 }
186 view.setViewStatus(ViewStatus.FINAL);
187 }
188
189 public ViewTypeService getViewTypeService(UifConstants.ViewType viewType) {
190 if (viewTypeServices != null) {
191 for (ViewTypeService typeService : viewTypeServices) {
192 if (viewType.equals(typeService.getViewTypeName())) {
193 return typeService;
194 }
195 }
196 }
197
198 return null;
199 }
200
201 public List<ViewTypeService> getViewTypeServices() {
202 return this.viewTypeServices;
203 }
204
205 public void setViewTypeServices(List<ViewTypeService> viewTypeServices) {
206 this.viewTypeServices = viewTypeServices;
207 }
208
209 protected DataDictionaryService getDataDictionaryService() {
210 return this.dataDictionaryService;
211 }
212
213 public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
214 this.dataDictionaryService = dataDictionaryService;
215 }
216
217 }