001: /*
002: * Copyright 2006-2007 The Kuali Foundation.
003: *
004: * Licensed under the Educational Community License, Version 1.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/ecl1.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.core.maintenance;
017:
018: import java.util.ArrayList;
019: import java.util.Collection;
020: import java.util.HashMap;
021: import java.util.List;
022: import java.util.Map;
023:
024: import org.kuali.RiceConstants;
025: import org.kuali.RicePropertyConstants;
026: import org.kuali.core.KualiModule;
027: import org.kuali.core.bo.user.AuthenticationUserId;
028: import org.kuali.core.bo.user.KualiModuleUser;
029: import org.kuali.core.bo.user.KualiModuleUserProperty;
030: import org.kuali.core.bo.user.UniversalUser;
031: import org.kuali.core.datadictionary.DataDictionaryDefinitionBase;
032: import org.kuali.core.datadictionary.MaintainableFieldDefinition;
033: import org.kuali.core.datadictionary.MaintainableSectionDefinition;
034: import org.kuali.core.document.Document;
035: import org.kuali.core.exceptions.UserNotFoundException;
036: import org.kuali.core.lookup.LookupUtils;
037: import org.kuali.core.service.DocumentService;
038: import org.kuali.core.service.KualiConfigurationService;
039: import org.kuali.core.service.KualiModuleService;
040: import org.kuali.core.service.KualiModuleUserPropertyService;
041: import org.kuali.core.service.UniversalUserService;
042: import org.kuali.core.web.ui.Field;
043: import org.kuali.core.web.ui.Row;
044: import org.kuali.core.web.ui.Section;
045: import org.kuali.core.web.ui.SectionBridge;
046: import org.kuali.rice.KNSServiceLocator;
047:
048: import edu.iu.uis.eden.exception.WorkflowException;
049:
050: public class UniversalUserMaintainable extends KualiMaintainableImpl {
051: private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger
052: .getLogger(UniversalUserMaintainable.class);
053:
054: private static KualiConfigurationService configService;
055: private static String userEditWorkgroupName;
056: private static boolean usersMaintainedByKuali;
057: private static DocumentService documentService;
058: private static UniversalUserService universalUserService;
059: private static KualiModuleService kualiModuleService;
060: private static KualiModuleUserPropertyService moduleUserPropertyService;
061:
062: @Override
063: public List getSections(Maintainable oldMaintainable) {
064: List sections = new ArrayList();
065: sections.addAll(getCoreSections(oldMaintainable));
066: sections.addAll(getModuleUserSections(oldMaintainable));
067: return sections;
068: }
069:
070: private List getModuleUserSections(Maintainable oldMaintainable) {
071: initStatics();
072: List<Section> sections = new ArrayList<Section>();
073: UniversalUser universalUser = (UniversalUser) getBusinessObject();
074: List<KualiModule> modules = kualiModuleService
075: .getInstalledModules();
076: DataDictionaryDefinitionBase.isParsingFile = false; // prevents from attempting to retrieve file name and line number (which throws an exception)
077:
078: // iterate over installed modules - create a section for each
079: for (KualiModule module : modules) {
080: MaintainableSectionDefinition sectionDef = new MaintainableSectionDefinition();
081: sectionDef.setTitle(module.getModuleName()
082: + " User Properties");
083:
084: KualiModuleUser moduleUser = null;
085: if (universalUser != null) {
086: moduleUser = universalUser.getModuleUser(module
087: .getModuleId());
088: }
089:
090: if (moduleUser == null) { // not sure when this would happen, but let's avoid an NPE
091: continue;
092: }
093:
094: List<String> userPropertyNames = module
095: .getModuleUserService().getPropertyList();
096:
097: // don't add a section if no properties have been defined for a module
098: if (userPropertyNames.size() == 0) {
099: continue;
100: }
101:
102: // add the UUID field to support proper linking of objects
103: MaintainableFieldDefinition fieldDef = new MaintainableFieldDefinition();
104: fieldDef.setName("personUniversalIdentifier");
105: sectionDef.addMaintainableItem(fieldDef);
106:
107: for (String propertyName : userPropertyNames) {
108: fieldDef = new MaintainableFieldDefinition();
109: fieldDef.setName(propertyName);
110: sectionDef.addMaintainableItem(fieldDef);
111: }
112:
113: try {
114: Section section = SectionBridge.toSection(sectionDef,
115: moduleUser, this , oldMaintainable,
116: getMaintenanceAction(),
117: isGenerateDefaultValues(),
118: isGenerateBlankRequiredValues(),
119: userPropertyNames);
120:
121: // update the property names for the form (to map into moduleUser Map property)
122: for (Row row : section.getRows()) {
123: for (Field field : row.getFields()) {
124: field.setPropertyName("moduleUsers("
125: + module.getModuleId() + ")."
126: + field.getPropertyName());
127:
128: // convert the field conversions to have the appropriate prefix for the module user sections
129: Map<String, String> fieldConversions = LookupUtils
130: .translateFieldConversions(field
131: .getFieldConversions());
132: Map<String, String> newFieldConversions = new HashMap<String, String>();
133: for (String fieldConversionSource : fieldConversions
134: .keySet()) {
135: String fieldConversionTarget = fieldConversions
136: .get(fieldConversionSource);
137: String newFieldConversionTarget = "moduleUsers("
138: + module.getModuleId()
139: + ")."
140: + fieldConversionTarget;
141: newFieldConversions.put(
142: fieldConversionSource,
143: newFieldConversionTarget);
144: }
145: field.setFieldConversions(newFieldConversions);
146:
147: // convert the lookup parameters to have the appropriate prefix for the module user sections
148: Map<String, String> lookupParameters = LookupUtils
149: .translateFieldConversions(field
150: .getLookupParameters());
151: Map<String, String> newLookupParameters = new HashMap<String, String>();
152: for (String lookupParameterSource : lookupParameters
153: .keySet()) {
154: String lookupParameterTarget = lookupParameters
155: .get(lookupParameterSource);
156: String newLookupParameterSource = "moduleUsers("
157: + module.getModuleId()
158: + ")."
159: + lookupParameterSource;
160: newLookupParameters.put(
161: newLookupParameterSource,
162: lookupParameterTarget);
163: }
164: field.setLookupParameters(newLookupParameters);
165: }
166: }
167: LOG.info("Updated Error key for section : "
168: + section.getSectionTitle() + " is "
169: + section.getErrorKey());
170:
171: sections.add(section);
172: } catch (IllegalAccessException ex) {
173: // ????
174: LOG.error("Error creating Section for module "
175: + module.getModuleId(), ex);
176: throw new RuntimeException(
177: "Error creating Section object for form.", ex);
178: } catch (InstantiationException ex) {
179: // ????
180: LOG.error("Error creating Section for module "
181: + module.getModuleId(), ex);
182: throw new RuntimeException(
183: "Error creating Section object for form.", ex);
184: }
185: }
186:
187: return sections;
188: }
189:
190: @Override
191: public void saveBusinessObject() {
192: initStatics();
193: // only attempt to save the UU object if the initiator is in the appropriate group
194: // get the group name that we need here
195: UniversalUser initiator = null;
196: try {
197: Document doc = documentService
198: .getByDocumentHeaderId(documentNumber);
199: if (doc != null) {
200: String initiatorId = doc.getDocumentHeader()
201: .getWorkflowDocument().getInitiatorNetworkId();
202: if (initiatorId != null) {
203: initiator = universalUserService
204: .getUniversalUser(new AuthenticationUserId(
205: initiatorId));
206: }
207: }
208: } catch (WorkflowException ex) {
209: LOG.error("unable to get initiator ID for document "
210: + documentNumber, ex);
211: } catch (UserNotFoundException ex) {
212: LOG.error(
213: "unable to get initator UniversalUser for for document "
214: + documentNumber, ex);
215: }
216: // only save the primary UniversalUser business object if the conditions are met
217: if (usersMaintainedByKuali && initiator != null
218: && initiator.isMember(userEditWorkgroupName)) {
219: super .saveBusinessObject();
220: }
221:
222: // save module user properties
223: UniversalUser user = (UniversalUser) getBusinessObject();
224: // retrieve the property objects from the database
225: Collection<KualiModuleUserProperty> props = moduleUserPropertyService
226: .getPropertiesForUser(user);
227: // iterate over the property map
228:
229: for (Map.Entry<String, Map<String, String>> moduleEntry : user
230: .getModuleProperties().entrySet()) {
231: String moduleId = moduleEntry.getKey();
232: for (Map.Entry<String, String> entry : moduleEntry
233: .getValue().entrySet()) {
234: String propertyName = entry.getKey();
235: String propertyValue = entry.getValue();
236: boolean propertyFound = false;
237: // find the associated business object
238: for (KualiModuleUserProperty prop : props) {
239: if (prop.getModuleId().equals(moduleId)
240: && prop.getName().equals(propertyName)) {
241: propertyFound = true;
242: String oldPropertyValue = prop.getValue();
243: // compare to value in the business object
244: // if changed, set the value in the BO and save it
245: if (oldPropertyValue == null
246: || !oldPropertyValue
247: .equals(propertyValue)) {
248: prop.setValue(propertyValue);
249: moduleUserPropertyService.save(prop);
250: }
251: }
252: }
253: // if the property was not found, create a new one and save it
254: if (!propertyFound) {
255: KualiModuleUserProperty newProp = new KualiModuleUserProperty();
256: newProp.setPersonUniversalIdentifier(user
257: .getPersonUniversalIdentifier());
258: newProp.setModuleId(moduleId);
259: newProp.setName(propertyName);
260: newProp.setValue(propertyValue);
261: moduleUserPropertyService.save(newProp);
262: props.add(newProp);
263: }
264: }
265: }
266: }
267:
268: private void initStatics() {
269: if (kualiModuleService == null) { // they're all set at the same time, so only need one check
270: configService = KNSServiceLocator
271: .getKualiConfigurationService();
272: universalUserService = KNSServiceLocator
273: .getUniversalUserService();
274: moduleUserPropertyService = KNSServiceLocator
275: .getKualiModuleUserPropertyService();
276: documentService = KNSServiceLocator.getDocumentService();
277: userEditWorkgroupName = configService
278: .getParameterValue(
279: RiceConstants.KNS_NAMESPACE,
280: RiceConstants.DetailTypes.UNIVERSAL_USER_DETAIL_TYPE,
281: RiceConstants.CoreApcParms.UNIVERSAL_USER_EDIT_WORKGROUP);
282: // check whether users are editable within Kuali
283: usersMaintainedByKuali = configService
284: .getPropertyAsBoolean(RiceConstants.MAINTAIN_USERS_LOCALLY_KEY);
285: kualiModuleService = KNSServiceLocator
286: .getKualiModuleService();
287: }
288: }
289:
290: /**
291: * @see org.kuali.core.maintenance.Maintainable#populateBusinessObject(java.util.Map)
292: */
293: public Map populateBusinessObject(Map fieldValues) {
294: // need to make sure that the UUID is populated first for later fields
295: if (fieldValues
296: .containsKey(RicePropertyConstants.PERSON_UNIVERSAL_IDENTIFIER)) {
297: ((UniversalUser) getBusinessObject())
298: .setPersonUniversalIdentifier((String) fieldValues
299: .get(RicePropertyConstants.PERSON_UNIVERSAL_IDENTIFIER));
300: }
301: return super .populateBusinessObject(fieldValues);
302: }
303:
304: /**
305: * @see org.kuali.core.maintenance.Maintainable#processAfterCopy()
306: */
307: public void processAfterCopy() {
308: UniversalUser user = (UniversalUser) businessObject;
309: user.setPersonUserIdentifier("");
310: }
311: }
|