1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.preferences.service.impl;
17
18 import java.util.ArrayList;
19 import java.util.Collection;
20 import java.util.HashMap;
21 import java.util.Map;
22 import java.util.Map.Entry;
23
24 import org.apache.commons.lang.StringUtils;
25 import org.kuali.rice.core.api.CoreApiServiceLocator;
26 import org.kuali.rice.core.api.config.property.ConfigContext;
27 import org.kuali.rice.core.api.config.property.ConfigurationService;
28 import org.kuali.rice.kew.api.KewApiConstants;
29 import org.kuali.rice.kew.api.preferences.Preferences;
30 import org.kuali.rice.kew.api.preferences.PreferencesService;
31 import org.kuali.rice.kew.exception.WorkflowServiceErrorException;
32 import org.kuali.rice.kew.exception.WorkflowServiceErrorImpl;
33 import org.kuali.rice.kew.service.KEWServiceLocator;
34 import org.kuali.rice.kew.useroptions.UserOptions;
35 import org.kuali.rice.kew.useroptions.UserOptionsService;
36
37
38
39
40
41
42 public class PreferencesServiceImpl implements PreferencesService {
43
44 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PreferencesServiceImpl.class);
45
46 private static Map<String, String> USER_OPTION_KEY_DEFAULT_MAP;
47
48 static {
49 USER_OPTION_KEY_DEFAULT_MAP = new HashMap<String, String>();
50 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.COLOR_APPROVED, "userOptions.default.color");
51 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.COLOR_CANCELED, "userOptions.default.color");
52 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.COLOR_DISAPPROVE_CANCEL, "userOptions.default.color");
53 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.COLOR_DISAPPROVED, "userOptions.default.color");
54 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.COLOR_ENROUTE, "userOptions.default.color");
55 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.COLOR_EXCEPTION, "userOptions.default.color");
56 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.COLOR_FINAL, "userOptions.default.color");
57 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.COLOR_INITIATED, "userOptions.default.color");
58 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.COLOR_PROCESSED, "userOptions.default.color");
59 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.COLOR_SAVED, "userOptions.default.color");
60 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.EMAIL_NOTIFICATION, "userOptions.default.email");
61 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.NOTIFY_PRIMARY_DELEGATION, "userOptions.default.notifyPrimary");
62 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.NOTIFY_SECONDARY_DELEGATION, "userOptions.default.notifySecondary");
63 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.OPEN_NEW_WINDOW, "userOptions.default.openNewWindow");
64 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.PAGE_SIZE, "userOptions.default.actionListSize");
65 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.REFRESH_RATE, "userOptions.default.refreshRate");
66 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.SHOW_ACTION_REQUESTED, "userOptions.default.showActionRequired");
67 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.SHOW_DATE_CREATED, "userOptions.default.showDateCreated");
68 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.SHOW_DOC_TYPE, "userOptions.default.showDocumentType");
69 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.SHOW_DOCUMENT_STATUS, "userOptions.default.showDocumentStatus");
70 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.SHOW_INITIATOR, "showInitiator");
71 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.SHOW_DELEGATOR, "userOptions.default.showDelegator");
72 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.SHOW_DOC_TITLE, "userOptions.default.showTitle");
73 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.SHOW_GROUP_REQUEST, "userOptions.default.showWorkgroupRequest");
74 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.SHOW_CLEAR_FYI, "userOptions.default.showClearFYI");
75 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.DELEGATOR_FILTER, "userOptions.default.delegatorFilterOnActionList");
76 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.PRIMARY_DELEGATE_FILTER, "userOptions.default.primaryDelegatorFilterOnActionList");
77 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.SHOW_DATE_APPROVED, "userOptions.default.showLastApprovedDate");
78 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.SHOW_CURRENT_NODE, "userOptions.default.showCurrentNode");
79 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.USE_OUT_BOX, KewApiConstants.USER_OPTIONS_DEFAULT_USE_OUTBOX_PARAM);
80 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.NOTIFY_ACKNOWLEDGE, "userOptions.default.notifyAcknowledge");
81 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.NOTIFY_APPROVE, "userOptions.default.notifyApprove");
82 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.NOTIFY_COMPLETE, "userOptions.default.notifyComplete");
83 USER_OPTION_KEY_DEFAULT_MAP.put(Preferences.KEYS.NOTIFY_FYI, "userOptions.default.notifyFYI");
84 }
85
86
87 public Preferences getPreferences(String principalId) {
88 if ( LOG.isDebugEnabled() ) {
89 LOG.debug("start preferences fetch user " + principalId);
90 }
91 Collection<UserOptions> options = getUserOptionService().findByWorkflowUser(principalId);
92 Map<String,UserOptions> optionMap = new HashMap<String, UserOptions>();
93 Map<String,String> optionValueMap = new HashMap<String, String>();
94 Map<String, String> documentTypeNotificationPreferences = new HashMap<String, String>();
95 for ( UserOptions option : options ) {
96 if(option.getOptionId().endsWith(KewApiConstants.DOCUMENT_TYPE_NOTIFICATION_PREFERENCE_SUFFIX)) {
97 String preferenceName = option.getOptionId();
98 preferenceName = StringUtils.substringBeforeLast(preferenceName, KewApiConstants.DOCUMENT_TYPE_NOTIFICATION_PREFERENCE_SUFFIX);
99 documentTypeNotificationPreferences.put(preferenceName, option.getOptionVal());
100 } else {
101 optionMap.put(option.getOptionId(), option);
102 }
103 }
104
105 ConfigurationService kcs = CoreApiServiceLocator.getKualiConfigurationService();
106
107 boolean isSaveRequired = false;
108
109 for (Map.Entry<String, String> entry : USER_OPTION_KEY_DEFAULT_MAP.entrySet()) {
110 String optionKey = entry.getKey();
111 String defaultValue = kcs.getPropertyValueAsString(entry.getValue());
112 if (LOG.isDebugEnabled()) {
113 LOG.debug("start fetch option " + optionKey + " user " + principalId);
114 }
115
116 UserOptions option = optionMap.get(optionKey);
117 if (option == null) {
118 if (LOG.isDebugEnabled()) {
119 LOG.debug("User option '"
120 + optionKey
121 + "' on user "
122 + principalId
123 + " has no stored value. Preferences will require save.");
124 }
125 option = new UserOptions();
126 option.setWorkflowId(principalId);
127 option.setOptionId(optionKey);
128 option.setOptionVal(defaultValue);
129 optionMap.put(optionKey, option);
130
131 if (!isSaveRequired) {
132 if (optionKey.equals(Preferences.KEYS.USE_OUT_BOX) && !ConfigContext.getCurrentContextConfig().getOutBoxOn()) {
133
134 } else {
135 isSaveRequired = true;
136 }
137 }
138 }
139 if (LOG.isDebugEnabled()) {
140 LOG.debug("End fetch option " + optionKey + " user " + principalId);
141 }
142
143 optionValueMap.put(optionKey, option.getOptionVal());
144 }
145
146
147
148
149
150 return Preferences.Builder.create(optionValueMap, documentTypeNotificationPreferences, isSaveRequired).build();
151 }
152
153 public void savePreferences(String principalId, Preferences preferences) {
154
155 if ( LOG.isDebugEnabled() ) {
156 LOG.debug("saving preferences user " + principalId);
157 }
158
159 validate(preferences);
160 Map<String,String> optionsMap = new HashMap<String,String>(50);
161
162 optionsMap.put(Preferences.KEYS.COLOR_DISAPPROVE_CANCEL, preferences.getColorDisapproveCancel());
163 optionsMap.put(Preferences.KEYS.COLOR_DISAPPROVED, preferences.getColorDisapproved());
164 optionsMap.put(Preferences.KEYS.COLOR_APPROVED, preferences.getColorApproved());
165 optionsMap.put(Preferences.KEYS.COLOR_CANCELED, preferences.getColorCanceled());
166 optionsMap.put(Preferences.KEYS.COLOR_SAVED, preferences.getColorSaved());
167 optionsMap.put(Preferences.KEYS.COLOR_ENROUTE, preferences.getColorEnroute());
168 optionsMap.put(Preferences.KEYS.COLOR_PROCESSED, preferences.getColorProcessed());
169 optionsMap.put(Preferences.KEYS.COLOR_INITIATED, preferences.getColorInitiated());
170 optionsMap.put(Preferences.KEYS.COLOR_FINAL, preferences.getColorFinal());
171 optionsMap.put(Preferences.KEYS.COLOR_EXCEPTION, preferences.getColorException());
172 optionsMap.put(Preferences.KEYS.REFRESH_RATE, preferences.getRefreshRate().trim());
173 optionsMap.put(Preferences.KEYS.OPEN_NEW_WINDOW, preferences.getOpenNewWindow());
174 optionsMap.put(Preferences.KEYS.SHOW_DOC_TYPE, preferences.getShowDocType());
175 optionsMap.put(Preferences.KEYS.SHOW_DOC_TITLE, preferences.getShowDocTitle());
176 optionsMap.put(Preferences.KEYS.SHOW_ACTION_REQUESTED, preferences.getShowActionRequested());
177 optionsMap.put(Preferences.KEYS.SHOW_INITIATOR, preferences.getShowInitiator());
178 optionsMap.put(Preferences.KEYS.SHOW_DELEGATOR, preferences.getShowDelegator());
179 optionsMap.put(Preferences.KEYS.SHOW_DATE_CREATED, preferences.getShowDateCreated());
180 optionsMap.put(Preferences.KEYS.SHOW_DOCUMENT_STATUS, preferences.getShowDocumentStatus());
181 optionsMap.put(Preferences.KEYS.SHOW_APP_DOC_STATUS, preferences.getShowAppDocStatus());
182 optionsMap.put(Preferences.KEYS.SHOW_GROUP_REQUEST, preferences.getShowWorkgroupRequest());
183 optionsMap.put(Preferences.KEYS.SHOW_CLEAR_FYI, preferences.getShowClearFyi());
184 optionsMap.put(Preferences.KEYS.PAGE_SIZE, preferences.getPageSize().trim());
185 optionsMap.put(Preferences.KEYS.EMAIL_NOTIFICATION, preferences.getEmailNotification());
186 optionsMap.put(Preferences.KEYS.NOTIFY_PRIMARY_DELEGATION, preferences.getNotifyPrimaryDelegation());
187 optionsMap.put(Preferences.KEYS.NOTIFY_SECONDARY_DELEGATION, preferences.getNotifySecondaryDelegation());
188 optionsMap.put(Preferences.KEYS.DELEGATOR_FILTER, preferences.getDelegatorFilter());
189 optionsMap.put(Preferences.KEYS.PRIMARY_DELEGATE_FILTER, preferences.getPrimaryDelegateFilter());
190 optionsMap.put(Preferences.KEYS.SHOW_DATE_APPROVED, preferences.getShowDateApproved());
191 optionsMap.put(Preferences.KEYS.SHOW_CURRENT_NODE, preferences.getShowCurrentNode());
192 optionsMap.put(Preferences.KEYS.NOTIFY_ACKNOWLEDGE, preferences.getNotifyAcknowledge());
193 optionsMap.put(Preferences.KEYS.NOTIFY_APPROVE, preferences.getNotifyApprove());
194 optionsMap.put(Preferences.KEYS.NOTIFY_COMPLETE, preferences.getNotifyComplete());
195 optionsMap.put(Preferences.KEYS.NOTIFY_FYI, preferences.getNotifyFYI());
196 if (ConfigContext.getCurrentContextConfig().getOutBoxOn()) {
197 optionsMap.put(Preferences.KEYS.USE_OUT_BOX, preferences.getUseOutbox());
198 }
199 for(Entry<String, String> documentTypePreference : preferences.getDocumentTypeNotificationPreferences().entrySet()) {
200 optionsMap.put(documentTypePreference.getKey() + KewApiConstants.DOCUMENT_TYPE_NOTIFICATION_PREFERENCE_SUFFIX, documentTypePreference.getValue());
201 }
202 getUserOptionService().save(principalId, optionsMap);
203
204
205
206 Preferences storedPreferences = this.getPreferences(principalId);
207 for(Entry<String, String> storedEntry : storedPreferences.getDocumentTypeNotificationPreferences().entrySet()) {
208 if(preferences.getDocumentTypeNotificationPreference(storedEntry.getKey()) == null) {
209 getUserOptionService().deleteUserOptions(getUserOptionService().findByOptionId(storedEntry.getKey() + KewApiConstants.DOCUMENT_TYPE_NOTIFICATION_PREFERENCE_SUFFIX, principalId));
210 }
211 }
212 if ( LOG.isDebugEnabled() ) {
213 LOG.debug("saved preferences user " + principalId);
214 }
215 }
216
217 private void validate(Preferences preferences) {
218 LOG.debug("validating preferences");
219
220 Collection errors = new ArrayList();
221 try {
222 new Integer(preferences.getRefreshRate().trim());
223 } catch (NumberFormatException e) {
224 errors.add(new WorkflowServiceErrorImpl("ActionList Refresh Rate must be in whole " +
225 "minutes", Preferences.KEYS.ERR_KEY_REFRESH_RATE_WHOLE_NUM));
226 } catch (NullPointerException e1) {
227 errors.add(new WorkflowServiceErrorImpl("ActionList Refresh Rate must be in whole " +
228 "minutes", Preferences.KEYS.ERR_KEY_REFRESH_RATE_WHOLE_NUM));
229 }
230
231 try {
232 if(new Integer(preferences.getPageSize().trim()) == 0){
233 errors.add(new WorkflowServiceErrorImpl("ActionList Page Size must be non-zero ",
234 Preferences.KEYS.ERR_KEY_ACTION_LIST_PAGE_SIZE_WHOLE_NUM));
235 }
236 } catch (NumberFormatException e) {
237 errors.add(new WorkflowServiceErrorImpl("ActionList Page Size must be in whole " +
238 "minutes", Preferences.KEYS.ERR_KEY_ACTION_LIST_PAGE_SIZE_WHOLE_NUM));
239 } catch (NullPointerException e1) {
240 errors.add(new WorkflowServiceErrorImpl("ActionList Page Size must be in whole " +
241 "minutes", Preferences.KEYS.ERR_KEY_ACTION_LIST_PAGE_SIZE_WHOLE_NUM));
242 }
243
244 LOG.debug("end validating preferences");
245 if (! errors.isEmpty()) {
246 throw new WorkflowServiceErrorException("Preference Validation Error", errors);
247 }
248 }
249
250 public UserOptionsService getUserOptionService() {
251 return (UserOptionsService) KEWServiceLocator.getService(
252 KEWServiceLocator.USER_OPTIONS_SRV);
253 }
254
255 private final class UserOptionsWrapper {
256
257 private final UserOptions userOptions;
258 private final boolean isSaveRequired;
259
260 public UserOptionsWrapper(UserOptions userOptions, boolean isSaveRequired) {
261 this.userOptions = userOptions;
262 this.isSaveRequired = isSaveRequired;
263 }
264
265 public UserOptions getUserOptions() {
266 return userOptions;
267 }
268
269 public boolean isSaveRequired() {
270 return isSaveRequired;
271 }
272 }
273 }
274
275