001 /*
002 * Copyright 2007 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.kew.removereplace.service.impl;
017
018 import java.util.ArrayList;
019 import java.util.List;
020
021 import org.apache.commons.lang.StringUtils;
022 import org.jdom.Element;
023 import org.kuali.rice.kew.exception.WorkflowException;
024 import org.kuali.rice.kew.exception.WorkflowRuntimeException;
025 import org.kuali.rice.kew.export.ExportDataSet;
026 import org.kuali.rice.kew.removereplace.RemoveReplaceDocument;
027 import org.kuali.rice.kew.removereplace.RuleTarget;
028 import org.kuali.rice.kew.removereplace.WorkgroupTarget;
029 import org.kuali.rice.kew.removereplace.dao.RemoveReplaceDocumentDAO;
030 import org.kuali.rice.kew.removereplace.service.RemoveReplaceDocumentService;
031 import org.kuali.rice.kew.rule.RuleBaseValues;
032 import org.kuali.rice.kew.rule.service.RuleService;
033 import org.kuali.rice.kew.service.KEWServiceLocator;
034 import org.kuali.rice.kew.service.WorkflowDocument;
035 import org.kuali.rice.kew.user.WorkflowUserId;
036 import org.kuali.rice.kew.web.session.UserSession;
037 import org.kuali.rice.kim.bo.Group;
038 import org.kuali.rice.kim.bo.Person;
039 import org.kuali.rice.kim.service.KIMServiceLocator;
040
041
042 public class RemoveReplaceDocumentServiceImpl implements RemoveReplaceDocumentService {
043
044 private RemoveReplaceDocumentDAO dao;
045
046 public void save(RemoveReplaceDocument document) {
047 if (document.getDocumentId() == null) {
048 throw new WorkflowRuntimeException("The given document has a null document ID. Please assign a document ID prior to saving.");
049 }
050 dao.save(document);
051 }
052
053 public RemoveReplaceDocument findById(Long documentId) {
054 return dao.findById(documentId);
055 }
056
057 public void blanketApprove(RemoveReplaceDocument document, UserSession user, String annotation) {
058 save(document);
059 try {
060 WorkflowDocument workflowDoc = new WorkflowDocument(user.getPrincipalId(), document.getDocumentId());
061 constructTitle(document, workflowDoc);
062 attachDocumentContent(document, workflowDoc);
063 workflowDoc.blanketApprove(annotation);
064 } catch (WorkflowException e) {
065 throw new WorkflowRuntimeException(e);
066 }
067 }
068
069 public void route(RemoveReplaceDocument document, UserSession user, String annotation) {
070 save(document);
071 try {
072 WorkflowDocument workflowDoc = new WorkflowDocument(user.getPrincipalId(), document.getDocumentId());
073 constructTitle(document, workflowDoc);
074 attachDocumentContent(document, workflowDoc);
075 workflowDoc.routeDocument(annotation);
076 } catch (WorkflowException e) {
077 throw new WorkflowRuntimeException(e);
078 }
079 }
080
081 protected void constructTitle(RemoveReplaceDocument document, WorkflowDocument workflowDoc) throws WorkflowException {
082 Person user = KIMServiceLocator.getPersonService().getPerson(document.getUserWorkflowId());
083 StringBuffer title = new StringBuffer();
084 if (document.getOperation().equals(RemoveReplaceDocument.REMOVE_OPERATION)) {
085 title.append("Removing " + user.getPrincipalName() + " from ");
086 } else if (document.getOperation().equals(RemoveReplaceDocument.REPLACE_OPERATION)) {
087 Person replaceWithUser = KIMServiceLocator.getPersonService().getPerson(document.getReplacementUserWorkflowId());
088 title.append("Replacing " + user.getPrincipalName() + " with " + replaceWithUser.getPrincipalName() + " in ");
089 }
090 title.append(document.getRuleTargets().size() + " rules and " + document.getWorkgroupTargets().size() + " workgroups");
091 workflowDoc.setTitle(title.toString());
092 }
093
094 /**
095 * Attaches document content to the WorkflowDocument for the given RemoveReplaceDocument.
096 */
097 protected void attachDocumentContent(RemoveReplaceDocument document, WorkflowDocument workflowDoc) {
098 try {
099 Person user = KIMServiceLocator.getPersonService().getPerson(document.getUserWorkflowId());
100 Element rootElement = new Element("removeReplaceUserDocument");
101 Element removeReplaceElement = null;
102 if (document.getOperation().equals(RemoveReplaceDocument.REMOVE_OPERATION)) {
103 removeReplaceElement = new Element("remove");
104 Element userElement = new Element("user");
105 userElement.setText(user.getPrincipalName());
106 removeReplaceElement.addContent(userElement);
107 } else if (document.getOperation().equals(RemoveReplaceDocument.REPLACE_OPERATION)) {
108 removeReplaceElement = new Element("replace");
109 Element userElement = new Element("user");
110 userElement.setText(user.getPrincipalName());
111 removeReplaceElement.addContent(userElement);
112 Element replaceWithElement = new Element("replaceWith");
113 Person replaceWithUser = KIMServiceLocator.getPersonService().getPerson(document.getReplacementUserWorkflowId());
114 replaceWithElement.setText(replaceWithUser.getPrincipalName());
115 removeReplaceElement.addContent(replaceWithElement);
116 } else {
117 throw new WorkflowRuntimeException("Invalid remove/replace operation specified: " + document.getOperation());
118 }
119 rootElement.addContent(removeReplaceElement);
120
121 // add rules
122 List<RuleBaseValues> rules = loadRules(document);
123 if (!rules.isEmpty()) {
124 ExportDataSet ruleDataSet = new ExportDataSet();
125 ruleDataSet.getRules().addAll(rules);
126 Element rulesElement = KEWServiceLocator.getRuleService().export(ruleDataSet);
127 removeReplaceElement.addContent(rulesElement);
128 }
129
130 // add workgroups
131 List<? extends Group> workgroups = loadWorkgroups(document);
132 if (!workgroups.isEmpty()) {
133 ExportDataSet workgroupDataSet = new ExportDataSet();
134 workgroupDataSet.getGroups().addAll(workgroups);
135 if (true) {
136 throw new UnsupportedOperationException("TODO: please implement this once we have xml export of groups working in KIM!");
137 }
138 }
139 // Element workgroupsElement = KEWServiceLocator.getWorkgroupService().export(workgroupDataSet);
140 // removeReplaceElement.addContent(workgroupsElement);
141 // }
142 // workflowDoc.setApplicationContent(XmlHelper.jotNode(rootElement));
143 } catch (Exception e) {
144 throw new WorkflowRuntimeException(e);
145 }
146 }
147
148 protected List<? extends Group> loadWorkgroups(RemoveReplaceDocument document) {
149 List<Group> workgroups = new ArrayList<Group>();
150 for (WorkgroupTarget workgroupTarget : document.getWorkgroupTargets()) {
151 Group group = KIMServiceLocator.getIdentityManagementService().getGroup(workgroupTarget.getWorkgroupId());
152 if (group == null) {
153 throw new WorkflowRuntimeException("Failed to locate workgroup to change with id " + workgroupTarget.getWorkgroupId());
154 }
155 workgroups.add(group);
156 }
157 return workgroups;
158 }
159
160 protected List<RuleBaseValues> loadRules(RemoveReplaceDocument document) {
161 List<RuleBaseValues> rules = new ArrayList<RuleBaseValues>();
162 for (RuleTarget ruleTarget : document.getRuleTargets()) {
163 RuleBaseValues rule = KEWServiceLocator.getRuleService().findRuleBaseValuesById(ruleTarget.getRuleId());
164 if (rule == null) {
165 throw new WorkflowRuntimeException("Failed to locate rule to change with id " + ruleTarget.getRuleId());
166 }
167 rules.add(rule);
168 }
169 return rules;
170 }
171
172
173 public void finalize(Long documentId) {
174 RemoveReplaceDocument document = findById(documentId);
175
176 if (document == null) {
177 throw new WorkflowRuntimeException("Failed to locate the RemoveReplaceDocument with id " + documentId);
178 }
179 if (StringUtils.isEmpty(document.getUserWorkflowId())) {
180 throw new WorkflowRuntimeException("RemoveReplaceDocument does not have a user id.");
181 }
182
183 List<Long> ruleIds = new ArrayList<Long>();
184 if (document.getRuleTargets() != null) {
185 for (RuleTarget ruleTarget : document.getRuleTargets()) {
186 ruleIds.add(ruleTarget.getRuleId());
187 }
188 }
189
190 List<String> workgroupIds = new ArrayList<String>();
191 if (document.getWorkgroupTargets() != null) {
192 for (WorkgroupTarget workgroupTarget : document.getWorkgroupTargets()) {
193 workgroupIds.add(workgroupTarget.getWorkgroupId());
194 }
195 }
196
197 RuleService ruleService = KEWServiceLocator.getRuleService();
198 /**
199 * TODO re-implement replacing of group membership using KIM!
200 */
201 //WorkgroupRoutingService workgroupRoutingService = KEWServiceLocator.getWorkgroupRoutingService();
202 try {
203 if (RemoveReplaceDocument.REPLACE_OPERATION.equals(document.getOperation())) {
204 if (StringUtils.isEmpty(document.getReplacementUserWorkflowId())) {
205 throw new WorkflowRuntimeException("Replacement operation was indicated but RemoveReplaceDocument does not have a replacement user id.");
206 }
207 ruleService.replaceRuleInvolvement(new WorkflowUserId(document.getUserWorkflowId()), new WorkflowUserId(document.getReplacementUserWorkflowId()), ruleIds, documentId);
208 //workgroupRoutingService.replaceWorkgroupInvolvement(new WorkflowUserId(document.getUserWorkflowId()), new WorkflowUserId(document.getReplacementUserWorkflowId()), workgroupIds, documentId);
209 } else if (RemoveReplaceDocument.REMOVE_OPERATION.equals(document.getOperation())) {
210 ruleService.removeRuleInvolvement(new WorkflowUserId(document.getUserWorkflowId()), ruleIds, documentId);
211 //workgroupRoutingService.removeWorkgroupInvolvement(new WorkflowUserId(document.getUserWorkflowId()), workgroupIds, documentId);
212 } else {
213 throw new WorkflowRuntimeException("Invalid operation was specified on the RemoveReplaceDocument: " + document.getOperation());
214 }
215 } catch (WorkflowException e) {
216 throw new WorkflowRuntimeException(e);
217 }
218 }
219
220 public void setRemoveReplaceDocumentDAO(RemoveReplaceDocumentDAO dao) {
221 this.dao = dao;
222 }
223
224 }