001: package org.tigris.scarab.actions;
002:
003: /* ================================================================
004: * Copyright (c) 2000-2003 CollabNet. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions are
008: * met:
009: *
010: * 1. Redistributions of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in the
015: * documentation and/or other materials provided with the distribution.
016: *
017: * 3. The end-user documentation included with the redistribution, if
018: * any, must include the following acknowlegement: "This product includes
019: * software developed by Collab.Net <http://www.Collab.Net/>."
020: * Alternately, this acknowlegement may appear in the software itself, if
021: * and wherever such third-party acknowlegements normally appear.
022: *
023: * 4. The hosted project names must not be used to endorse or promote
024: * products derived from this software without prior written
025: * permission. For written permission, please contact info@collab.net.
026: *
027: * 5. Products derived from this software may not use the "Tigris" or
028: * "Scarab" names nor may "Tigris" or "Scarab" appear in their names without
029: * prior written permission of Collab.Net.
030: *
031: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
032: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
033: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
034: * IN NO EVENT SHALL COLLAB.NET OR ITS CONTRIBUTORS BE LIABLE FOR ANY
035: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
036: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
037: * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
038: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
039: * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
040: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
041: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
042: *
043: * ====================================================================
044: *
045: * This software consists of voluntary contributions made by many
046: * individuals on behalf of Collab.Net.
047: */
048:
049: import java.util.ArrayList;
050: import java.util.HashMap;
051: import java.util.HashSet;
052: import java.util.Iterator;
053: import java.util.List;
054: import java.util.Map;
055: import java.util.Set;
056:
057: import org.apache.fulcrum.parser.ParameterParser;
058: import org.apache.torque.TorqueException;
059: import org.apache.turbine.RunData;
060: import org.apache.turbine.TemplateContext;
061: import org.tigris.scarab.actions.base.BaseModifyIssue;
062: import org.tigris.scarab.notification.NotificationManagerFactory;
063: import org.tigris.scarab.om.ActivitySet;
064: import org.tigris.scarab.notification.ActivityType;
065: import org.tigris.scarab.om.Attachment;
066: import org.tigris.scarab.om.Attribute;
067: import org.tigris.scarab.om.AttributeManager;
068: import org.tigris.scarab.om.AttributeValue;
069: import org.tigris.scarab.om.Issue;
070: import org.tigris.scarab.om.Module;
071: import org.tigris.scarab.om.ScarabUser;
072: import org.tigris.scarab.om.ScarabUserManager;
073: import org.tigris.scarab.tools.ScarabRequestTool;
074: import org.tigris.scarab.tools.localization.L10NKeySet;
075: import org.tigris.scarab.tools.localization.L10NMessage;
076:
077: /**
078: * This class is responsible for assigning users to attributes.
079: *
080: * @author <a href="mailto:jmcnally@collab.net">John D. McNally</a>
081: * @version $Id: AssignIssue.java 10191 2006-06-26 23:02:22Z dabbous $
082: */
083: public class AssignIssue extends BaseModifyIssue {
084: private static final String ADD_USER = "add_user";
085: private static final String SELECTED_USER = "select_user";
086:
087: private static int USERS_ADDED = 1;
088: private static int USERS_REMOVED = 2;
089: private static int ERR_NO_USERS_SELECTED = 3;
090:
091: /**
092: * Adds users to temporary working list.
093: */
094: public void doAdd(RunData data, TemplateContext context)
095: throws Exception {
096: int returnCode = 0;
097: ScarabUser user = (ScarabUser) data.getUser();
098: ScarabRequestTool scarabR = getScarabRequestTool(context);
099: Module module = scarabR.getCurrentModule();
100: ParameterParser params = data.getParameters();
101: StringBuffer msg = new StringBuffer();
102: String[] userIds = params.getStrings(ADD_USER);
103: Map userAttributes = new HashMap();
104: if (userIds != null) {
105: for (int i = 0; i < userIds.length; i++) {
106: userAttributes.put(userIds[i], params.get("user_attr_"
107: + userIds[i]));
108: }
109: returnCode = addUsersToList(user, module, userAttributes,
110: msg);
111: if (returnCode == USERS_ADDED) {
112: scarabR
113: .setConfirmMessage(L10NKeySet.SelectedUsersWereAdded);
114: }
115: if (returnCode == USERS_REMOVED) {
116: L10NMessage l10nMsg = new L10NMessage(
117: L10NKeySet.UserAttributeRemoved, msg.toString());
118: scarabR.setAlertMessage(l10nMsg);
119: }
120: if (returnCode == ERR_NO_USERS_SELECTED) {
121: scarabR.setAlertMessage(L10NKeySet.NoUsersSelected);
122: }
123: }
124: }
125:
126: /**
127: * Adds the current user to the temporary working list.
128: * @param data
129: * @param context
130: * @throws Exception
131: */
132: public void doAddmyself(RunData data, TemplateContext context)
133: throws Exception {
134: ScarabRequestTool scarabR = getScarabRequestTool(context);
135: ScarabUser user = (ScarabUser) data.getUser();
136: String attributeId = data.getParameters().get(
137: "myself_attribute");
138: String userId = user.getUserId().toString();
139: Map map = new HashMap();
140: map.put(userId, attributeId);
141: StringBuffer msg = new StringBuffer();
142: int returnCode = addUsersToList(user, scarabR
143: .getCurrentModule(), map, msg);
144: if (returnCode == USERS_ADDED) {
145: scarabR
146: .setConfirmMessage(L10NKeySet.SelectedUsersWereAdded);
147: }
148: if (returnCode == USERS_REMOVED) {
149: L10NMessage l10nMsg = new L10NMessage(
150: L10NKeySet.UserAttributeRemoved, msg.toString());
151: scarabR.setAlertMessage(l10nMsg);
152: }
153: if (returnCode == ERR_NO_USERS_SELECTED) {
154: scarabR.setAlertMessage(L10NKeySet.NoUsersSelected);
155: }
156: }
157:
158: /**
159: * Adds the current user to the temporary working list.
160: * @param data
161: * @param context
162: * @throws Exception
163: */
164: public void doRemovemyself(RunData data, TemplateContext context)
165: throws Exception {
166: ScarabRequestTool scarabR = this .getScarabRequestTool(context);
167: ScarabUser user = (ScarabUser) data.getUser();
168: Integer myUid = user.getUserId();
169: Issue issue = scarabR.getIssue();
170: Set userSet = issue.getAssociatedUsers();
171: Iterator iter = userSet.iterator();
172: int removeCounter = 0;
173: int index = 0;
174: while (iter.hasNext()) {
175: ArrayList entry = (ArrayList) iter.next();
176: ScarabUser su = (ScarabUser) entry.get(1);
177: if (su.getUserId().equals(myUid)) {
178: userSet.remove(entry); // now the iterator is potentially invalid
179: iter = userSet.iterator(); // rebuild the iterator (suboptimal)
180: removeCounter++;
181: }
182: }
183: if (removeCounter > 0) {
184: scarabR
185: .setConfirmMessage(L10NKeySet.SelectedUsersWereRemoved);
186: } else {
187: scarabR.setAlertMessage(L10NKeySet.NoUsersSelected);
188: }
189: }
190:
191: /**
192: * Decoupled method that adds users to the temporary working list of the AssignIssue screen.
193: * @param user Currently connected user
194: * @param module Current module (to check availaible userattributes)
195: * @param userAttributes Map containing pairs userId-userAttrId
196: * @param msg Output parameter that will containt the removed users if applicable.
197: * @return
198: * @throws Exception
199: * @throws TorqueException
200: */
201: private int addUsersToList(ScarabUser user, Module module,
202: Map userAttributes, StringBuffer msg) throws Exception,
203: TorqueException {
204: int returnCode;
205: Map userMap = user.getAssociatedUsersMap();
206: if (userAttributes != null && userAttributes.size() > 0) {
207: boolean isUserAttrRemoved = false;
208: List removedUserAttrs = null;
209: for (Iterator it = userAttributes.keySet().iterator(); it
210: .hasNext();) {
211: String userId = (String) it.next();
212: List item = new ArrayList();
213: String attrId = (String) userAttributes.get(userId);
214: Attribute attribute = AttributeManager
215: .getInstance(new Integer(attrId));
216: ScarabUser su = ScarabUserManager
217: .getInstance(new Integer(userId));
218: item.add(attribute);
219: item.add(su);
220: List issues = (List) user.getAssignIssuesList();
221: for (int j = 0; j < issues.size(); j++) {
222: Issue issue = (Issue) issues.get(j);
223: Long issueId = issue.getIssueId();
224: Set userList = (Set) userMap.get(issueId);
225: if (userList == null) {
226: userList = new HashSet();
227: }
228: List attributeList = module.getUserAttributes(issue
229: .getIssueType(), true);
230: if (!attributeList.contains(attribute)) {
231: if (removedUserAttrs == null) {
232: removedUserAttrs = new ArrayList();
233: removedUserAttrs.add(attribute);
234: msg.append("'").append(attribute.getName())
235: .append("'");
236: } else if (!removedUserAttrs
237: .contains(attribute)) {
238: removedUserAttrs.add(attribute);
239: msg.append(", '").append(
240: attribute.getName()).append("'");
241: }
242: isUserAttrRemoved = true;
243: } else {
244: userList.add(item);
245: // userMap.put(issueId, userList);
246: // user.setAssociatedUsersMap(userMap);
247: }
248: }
249: }
250: if (!isUserAttrRemoved) {
251: returnCode = USERS_ADDED;
252: } else {
253: returnCode = USERS_REMOVED;
254: }
255: } else {
256: returnCode = ERR_NO_USERS_SELECTED;
257: }
258: return returnCode;
259: }
260:
261: /**
262: * Removes users from temporary working list.
263: */
264: private void remove(RunData data, TemplateContext context,
265: Long issueId) throws Exception {
266: ScarabUser user = (ScarabUser) data.getUser();
267: ScarabRequestTool scarabR = getScarabRequestTool(context);
268: Set userList = (Set) user.getAssociatedUsersMap().get(issueId);
269: ParameterParser params = data.getParameters();
270: String[] selectedUsers = params.getStrings(SELECTED_USER);
271: if (selectedUsers != null && selectedUsers.length > 0) {
272: for (int i = 0; i < selectedUsers.length; i++) {
273: List item = new ArrayList(2);
274: String selectedUser = selectedUsers[i];
275: String userId = selectedUser.substring(1, selectedUser
276: .indexOf('_') - 1);
277: String attrId = selectedUser.substring(selectedUser
278: .indexOf('_') + 1, selectedUser.length());
279: Attribute attribute = AttributeManager
280: .getInstance(new Integer(attrId));
281: ScarabUser su = ScarabUserManager
282: .getInstance(new Integer(userId));
283: item.add(attribute);
284: item.add(su);
285: userList.remove(item);
286: }
287: scarabR
288: .setConfirmMessage(L10NKeySet.SelectedUsersWereRemoved);
289: } else {
290: scarabR.setAlertMessage(L10NKeySet.NoUsersSelected);
291: }
292: }
293:
294: /**
295: * Changes the user attribute a user is associated with.
296: */
297: private void update(RunData data, TemplateContext context,
298: Long issueId) throws Exception {
299: ScarabUser user = (ScarabUser) data.getUser();
300: ScarabRequestTool scarabR = getScarabRequestTool(context);
301: Set userList = (Set) user.getAssociatedUsersMap().get(issueId);
302: ParameterParser params = data.getParameters();
303: String[] selectedUsers = params.getStrings(SELECTED_USER);
304: if (selectedUsers != null && selectedUsers.length > 0) {
305: for (int i = 0; i < selectedUsers.length; i++) {
306: String selectedUser = selectedUsers[i];
307: String userId = selectedUser.substring(1, selectedUser
308: .indexOf('_') - 1);
309: String attrId = selectedUser.substring(selectedUser
310: .indexOf('_') + 1, selectedUser.length());
311: Attribute attribute = AttributeManager
312: .getInstance(new Integer(attrId));
313: ScarabUser su = ScarabUserManager
314: .getInstance(new Integer(userId));
315: List item = new ArrayList(2);
316: List newItem = new ArrayList(2);
317: item.add(attribute);
318: item.add(su);
319: userList.remove(item);
320:
321: String newKey = "asso_user_{" + userId + "}_attr_{"
322: + attrId + "}_issue_{" + issueId + '}';
323: String newAttrId = params.get(newKey);
324: Attribute newAttribute = AttributeManager
325: .getInstance(new Integer(newAttrId));
326: newItem.add(newAttribute);
327: newItem.add(su);
328: userList.add(newItem);
329: }
330: scarabR
331: .setConfirmMessage(L10NKeySet.SelectedUsersWereModified);
332: } else {
333: scarabR.setAlertMessage(L10NKeySet.NoUsersSelected);
334: }
335: }
336:
337: public void doSave(RunData data, TemplateContext context)
338: throws Exception {
339: ScarabUser user = (ScarabUser) data.getUser();
340: ScarabRequestTool scarabR = getScarabRequestTool(context);
341: List issues = null;
342: String singleIssueId = data.getParameters().getString("id");
343: if (singleIssueId != null) {
344: Issue issue = scarabR.getIssue(singleIssueId);
345: if (issue != null) {
346: issues = new ArrayList();
347: issues.add(issue);
348: }
349: } else {
350: issues = (List) ((ScarabUser) data.getUser())
351: .getAssignIssuesList();
352: }
353:
354: Map userMap = user.getAssociatedUsersMap();
355: ScarabUser assigner = (ScarabUser) data.getUser();
356: String reason = data.getParameters().getString("reason", "");
357: Attachment attachment = null;
358: ActivitySet activitySet = null;
359: boolean isUserAttrRemoved = false;
360: StringBuffer msg = new StringBuffer();
361: List removedUserAttrs = null;
362:
363: for (int i = 0; i < issues.size(); i++) {
364: Issue issue = (Issue) issues.get(i);
365: Set userList = (Set) userMap.get(issue.getIssueId());
366: List oldAssignees = issue.getUserAttributeValues();
367: List attributeList = scarabR.getCurrentModule()
368: .getUserAttributes(issue.getIssueType(), true);
369: // save attachment with user-provided reason
370: if (reason != null && reason.length() > 0) {
371: attachment = new Attachment();
372: attachment.setData(reason);
373: attachment.setName("comment");
374: attachment.setTextFields(assigner, issue,
375: Attachment.MODIFICATION__PK);
376: attachment.save();
377: }
378:
379: // loops through users in temporary working list
380: for (Iterator iter = userList.iterator(); iter.hasNext();) {
381: List item = (List) iter.next();
382: Attribute newAttr = (Attribute) item.get(0);
383: ScarabUser assignee = (ScarabUser) item.get(1);
384: Integer assigneeId = assignee.getUserId();
385: boolean alreadyAssigned = false;
386: if (!attributeList.contains(newAttr)) {
387: if (removedUserAttrs == null) {
388: removedUserAttrs = new ArrayList();
389: removedUserAttrs.add(newAttr);
390: msg.append("'").append(newAttr.getName())
391: .append("'");
392: } else if (!removedUserAttrs.contains(newAttr)) {
393: removedUserAttrs.add(newAttr);
394: msg.append(", '").append(newAttr.getName())
395: .append("'");
396: }
397: isUserAttrRemoved = true;
398: } else {
399: for (int k = 0; k < oldAssignees.size(); k++) {
400: AttributeValue oldAttVal = (AttributeValue) oldAssignees
401: .get(k);
402: Attribute oldAttr = oldAttVal.getAttribute();
403: // ignore already assigned users
404: if (assigneeId.equals(oldAttVal.getUserId())) {
405: // unless user has different attribute id, then
406: // switch their user attribute
407: if (!newAttr.getAttributeId().equals(
408: oldAttr.getAttributeId())) {
409: List tmpItem = new ArrayList();
410: tmpItem.add(newAttr);
411: tmpItem.add(assignee);
412: if (!userList.contains(tmpItem)) {
413: alreadyAssigned = true;
414: activitySet = issue
415: .changeUserAttributeValue(
416: activitySet,
417: assignee, assigner,
418: oldAttVal, newAttr,
419: attachment);
420: }
421: } else {
422: alreadyAssigned = true;
423: }
424: }
425: }
426: // if user was not already assigned, assign them
427: if (!alreadyAssigned) {
428: activitySet = issue
429: .assignUser(activitySet, assignee,
430: assigner, newAttr, attachment);
431: }
432: }
433: }
434:
435: // loops thru previously assigned users to find ones that
436: // have been removed
437: for (int m = 0; m < oldAssignees.size(); m++) {
438: boolean userStillAssigned = false;
439: AttributeValue oldAttVal = (AttributeValue) oldAssignees
440: .get(m);
441: for (Iterator iter = userList.iterator(); iter
442: .hasNext();) {
443: List item = (List) iter.next();
444: Attribute attr = (Attribute) item.get(0);
445: ScarabUser su = (ScarabUser) item.get(1);
446: if (su.getUserId().equals(oldAttVal.getUserId())
447: && attr.getAttributeId().equals(
448: oldAttVal.getAttributeId())) {
449: userStillAssigned = true;
450: }
451: }
452: if (!userStillAssigned) {
453: ScarabUser assignee = scarabR.getUser(oldAttVal
454: .getUserId());
455: // delete the user
456: activitySet = issue.deleteUser(activitySet,
457: assignee, assigner, oldAttVal, attachment);
458: }
459: }
460: if (activitySet != null) {
461: try {
462: NotificationManagerFactory
463: .getInstance()
464: .addActivityNotification(
465: ActivityType.USER_ATTRIBUTE_CHANGED,
466: activitySet, issue, user);
467: } catch (Exception e) {
468: L10NMessage l10nMessage = new L10NMessage(
469: EMAIL_ERROR, e);
470: scarabR.setAlertMessage(l10nMessage);
471: }
472: }
473: }
474: if (isUserAttrRemoved) {
475: L10NMessage l10nMsg = new L10NMessage(
476: L10NKeySet.UserAttributeRemoved, msg.toString());
477: scarabR.setAlertMessage(l10nMsg);
478: }
479:
480: Object alertMessage = scarabR.getAlertMessage();
481: if (alertMessage == null
482: || alertMessage.toString().length() == 0) {
483: scarabR.setConfirmMessage(DEFAULT_MSG);
484: }
485: }
486:
487: public void doPerform(RunData data, TemplateContext context)
488: throws Exception {
489:
490: Object[] keys = data.getParameters().getKeys();
491: try {
492: for (int i = 0; i < keys.length; i++) {
493: String key = keys[i].toString();
494: if (key.startsWith("eventsubmit_doremove")) {
495: String issueId = key.substring(21);
496: remove(data, context, new Long(issueId));
497: } else if (key.startsWith("eventsubmit_doupdate")) {
498: String issueId = key.substring(21);
499: update(data, context, new Long(issueId));
500: }
501: }
502: } catch (NumberFormatException nfe) // new Integer(issueId) above could fail
503: {
504: getScarabRequestTool(context).setAlertMessage(
505: L10NKeySet.BadIntegerConversion);
506: }
507: }
508:
509: }
|