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.HashMap;
050: import java.util.Iterator;
051: import java.util.List;
052:
053: import org.apache.commons.collections.MapIterator;
054: import org.apache.commons.collections.map.LinkedMap;
055: import org.apache.commons.lang.StringUtils;
056: import org.apache.fulcrum.intake.model.Group;
057: import org.apache.torque.om.NumberKey;
058: import org.apache.turbine.RunData;
059: import org.apache.turbine.TemplateContext;
060: import org.apache.turbine.tool.IntakeTool;
061: import org.tigris.scarab.actions.base.RequireLoginFirstAction;
062: import org.tigris.scarab.attribute.OptionAttribute;
063: import org.tigris.scarab.om.ActivitySet;
064: import org.tigris.scarab.om.ActivitySetManager;
065: import org.tigris.scarab.om.ActivitySetTypePeer;
066: import org.tigris.scarab.om.AttributeOption;
067: import org.tigris.scarab.om.AttributeOptionManager;
068: import org.tigris.scarab.om.AttributeValue;
069: import org.tigris.scarab.om.Issue;
070: import org.tigris.scarab.om.IssueManager;
071: import org.tigris.scarab.om.IssueTemplateInfo;
072: import org.tigris.scarab.om.IssueTemplateInfoPeer;
073: import org.tigris.scarab.om.IssueType;
074: import org.tigris.scarab.om.Module;
075: import org.tigris.scarab.om.ScarabUser;
076: import org.tigris.scarab.om.Scope;
077: import org.tigris.scarab.tools.ScarabLocalizationTool;
078: import org.tigris.scarab.tools.ScarabRequestTool;
079: import org.tigris.scarab.tools.localization.L10NKeySet;
080: import org.tigris.scarab.util.ScarabConstants;
081: import org.tigris.scarab.util.ScarabException;
082:
083: /**
084: * This class is responsible for report managing issue entry
085: * templates.
086: *
087: * @author <a href="mailto:elicia@collab.net">Elicia David</a>
088: * @version $Id: TemplateList.java 10020 2006-03-16 16:19:13Z jorgeuriarte $
089: */
090: public class TemplateList extends RequireLoginFirstAction {
091: /**
092: * Creates new template.
093: */
094: public void doCreatenew(RunData data, TemplateContext context)
095: throws Exception {
096: IntakeTool intake = getIntakeTool(context);
097: ScarabRequestTool scarabR = getScarabRequestTool(context);
098: ScarabLocalizationTool l10n = getLocalizationTool(context);
099: ScarabUser user = (ScarabUser) data.getUser();
100: Issue issue = scarabR.getIssueTemplate();
101: if (issue == null) {
102: scarabR.setAlertMessage(L10NKeySet.IssueTypeNotAvailable);
103: return;
104: }
105:
106: LinkedMap avMap = issue.getModuleAttributeValuesMap();
107: AttributeValue aval = null;
108: Group group = null;
109:
110: IssueTemplateInfo info = scarabR.getIssueTemplateInfo();
111: Group infoGroup = intake.get("IssueTemplateInfo", info
112: .getQueryKey());
113: Group issueGroup = intake.get("Issue", issue.getQueryKey());
114: ActivitySet activitySet = null;
115:
116: if (intake.isAllValid()) {
117: issueGroup.setProperties(issue);
118: infoGroup.setProperties(info);
119: if (checkForDupes(info, infoGroup.get("Name").toString(),
120: user, issue)) {
121: scarabR
122: .setAlertMessage(L10NKeySet.DuplicateTemplateName);
123: } else {
124: boolean atLeastOne = false;
125: MapIterator iter = avMap.mapIterator();
126: if (iter.hasNext()) {
127: // Save activitySet record
128: activitySet = ActivitySetManager.getInstance(
129: ActivitySetTypePeer.CREATE_ISSUE__PK, user);
130: activitySet.save();
131: while (iter.hasNext()) {
132: aval = (AttributeValue) avMap.get(iter.next());
133: group = intake.get("AttributeValue", aval
134: .getQueryKey(), false);
135: String value = null;
136: if (group != null) {
137: if (aval instanceof OptionAttribute) {
138: value = group.get("OptionId")
139: .toString();
140: } else {
141: value = group.get("Value").toString();
142: }
143: if (StringUtils.isNotEmpty(value)) {
144: atLeastOne = true;
145: aval.startActivitySet(activitySet);
146: group.setProperties(aval);
147: }
148: }
149: }
150: }
151: if (atLeastOne) {
152: issue.setCreatedTransId(activitySet
153: .getActivitySetId());
154: issue.save();
155: info.setIssueId(issue.getIssueId());
156:
157: // Save template info
158: info.saveAndSendEmail(user, scarabR
159: .getCurrentModule(), context);
160:
161: // For a module-scoped template which is now
162: // pending approval, the user may not have
163: // permission to edit the new issue template.
164: if (info.canEdit(user)) {
165: data.getParameters().add("templateId",
166: issue.getIssueId().toString());
167: scarabR
168: .setConfirmMessage(L10NKeySet.NewTemplateCreated);
169: } else {
170: // Display the list of issue templates.
171: scarabR.setInfoMessage(l10n.format(
172: "NotifyPendingApproval", l10n.get(
173: "Template").toLowerCase()));
174: setTarget(data, "TemplateList.vm");
175: doPerform(data, context);
176: }
177: } else {
178: scarabR
179: .setAlertMessage(L10NKeySet.AtLeastOneAttributeForTemplate);
180: }
181: }
182: } else {
183: scarabR.setAlertMessage(ERROR_MESSAGE);
184: }
185: }
186:
187: /**
188: * Edits template's attribute values.
189: */
190: public void doEditvalues(RunData data, TemplateContext context)
191: throws Exception {
192: IntakeTool intake = getIntakeTool(context);
193: ScarabRequestTool scarabR = getScarabRequestTool(context);
194: ScarabLocalizationTool l10n = getLocalizationTool(context);
195: ScarabUser user = (ScarabUser) data.getUser();
196: Issue issue = scarabR.getIssueTemplate();
197:
198: LinkedMap avMap = issue.getModuleAttributeValuesMap();
199: AttributeValue aval = null;
200: Group group = null;
201: Group issueGroup = intake.get("Issue", issue.getQueryKey());
202: issueGroup.setProperties(issue);
203:
204: if (intake.isAllValid()) {
205: AttributeValue aval2 = null;
206: HashMap newAttVals = new HashMap();
207: boolean modifiedAttribute = false;
208:
209: Iterator iter = avMap.mapIterator();
210: while (iter.hasNext()) {
211: aval = (AttributeValue) avMap.get(iter.next());
212: aval2 = AttributeValue.getNewInstance(aval
213: .getAttributeId(), aval.getIssue());
214: aval2.setProperties(aval);
215: group = intake.get("AttributeValue",
216: aval.getQueryKey(), false);
217: if (group != null) {
218: String newValue = "";
219: String oldValue = "";
220: if (aval instanceof OptionAttribute) {
221: newValue = group.get("OptionId").toString();
222: oldValue = aval.getOptionIdAsString();
223:
224: if (!newValue.equals("")) {
225: AttributeOption newAttributeOption = AttributeOptionManager
226: .getInstance(new Integer(newValue));
227: newValue = newAttributeOption.getName();
228: }
229: if (!oldValue.equals("")) {
230: Integer oldOptionId = aval.getOptionId();
231: AttributeOption oldAttributeOption = AttributeOptionManager
232: .getInstance(oldOptionId);
233: oldValue = oldAttributeOption.getName();
234: }
235:
236: } else {
237: newValue = group.get("Value").toString();
238: oldValue = aval.getValue();
239: }
240: // A value has been entered for the attribute.
241: // The old value is different from the new, or is unset:
242: // Set new value.
243: if (newValue.trim().length() > 0
244: && (oldValue == null || !newValue.trim()
245: .equals(oldValue.trim()))) {
246: group.setProperties(aval2);
247: newAttVals.put(aval.getAttributeId(), aval2);
248: modifiedAttribute = true;
249: }
250: // The attribute is being undefined.
251: else if (oldValue != null
252: && newValue.trim().length() == 0
253: && oldValue.trim().length() != 0) {
254: aval2.setValue(null);
255: newAttVals.put(aval.getAttributeId(), aval2);
256: modifiedAttribute = true;
257: }
258: }
259: }
260: //save data only if there is a change
261: if (modifiedAttribute) {
262: issue.setAttributeValues(null, newAttVals, null, user);
263: intake.removeAll();
264: }
265: scarabR.setConfirmMessage(L10NKeySet.TemplateModified);
266: } else {
267: scarabR.setAlertMessage(ERROR_MESSAGE);
268: }
269: }
270:
271: /**
272: * Edits templates's basic information.
273: */
274: public boolean doEdittemplateinfo(RunData data,
275: TemplateContext context) throws Exception {
276: IntakeTool intake = getIntakeTool(context);
277: ScarabRequestTool scarabR = getScarabRequestTool(context);
278: ScarabLocalizationTool l10n = getLocalizationTool(context);
279: ScarabUser user = (ScarabUser) data.getUser();
280: Issue issue = scarabR.getIssueTemplate();
281: boolean success = true;
282:
283: IssueTemplateInfo info = scarabR.getIssueTemplateInfo();
284: Group infoGroup = intake.get("IssueTemplateInfo", info
285: .getQueryKey());
286:
287: if (intake.isAllValid()) {
288: infoGroup.setProperties(info);
289: info.setIssueId(issue.getIssueId());
290: if (checkForDupes(info, infoGroup.get("Name").toString(),
291: user, issue)) {
292: success = false;
293: scarabR
294: .setAlertMessage(L10NKeySet.DuplicateTemplateName);
295: } else {
296: // Save template info
297: info.saveAndSendEmail(user, scarabR.getCurrentModule(),
298: context);
299: data.getParameters().add("templateId",
300: issue.getIssueId().toString());
301: if (info.canEdit(user)) {
302: scarabR
303: .setConfirmMessage(L10NKeySet.TemplateModified);
304: } else {
305: scarabR.setInfoMessage(l10n.format(
306: "NotifyPendingApproval", l10n.get(
307: "Template").toLowerCase()));
308: setTarget(data, data.getParameters().getString(
309: ScarabConstants.CANCEL_TEMPLATE));
310: }
311: }
312: } else {
313: success = false;
314: scarabR.setAlertMessage(ERROR_MESSAGE);
315: }
316: return success;
317: }
318:
319: public void doDeletetemplates(RunData data, TemplateContext context)
320: throws Exception {
321: ScarabLocalizationTool l10n = getLocalizationTool(context);
322: ScarabRequestTool scarabR = getScarabRequestTool(context);
323: Object[] keys = data.getParameters().getKeys();
324: String key;
325: String templateId;
326: ScarabUser user = (ScarabUser) data.getUser();
327: boolean atLeastOne = false;
328: boolean success = true;
329:
330: for (int i = 0; i < keys.length; i++) {
331: key = keys[i].toString();
332: if (key.startsWith("delete_")) {
333: atLeastOne = true;
334: templateId = key.substring(7);
335: try {
336: Issue issue = IssueManager.getInstance(
337: new NumberKey(templateId), false);
338: if (issue == null) {
339: throw new Exception(l10n
340: .get("CouldNotLocateTemplateToDelete")); //EXCEPTION
341: }
342: issue.deleteItem(user);
343: } catch (ScarabException e) {
344: success = false;
345: scarabR.setAlertMessage(NO_PERMISSION_MESSAGE);
346: } catch (Exception e) {
347: success = false;
348: scarabR.setAlertMessage(l10n.getMessage(e));
349: }
350: }
351: }
352: if (!atLeastOne) {
353: scarabR.setAlertMessage(L10NKeySet.NoTemplateSelected);
354: } else if (success) {
355: scarabR.setConfirmMessage(L10NKeySet.TemplateDeleted);
356: }
357: }
358:
359: public void doUsetemplate(RunData data, TemplateContext context)
360: throws Exception {
361: IntakeTool intake = getIntakeTool(context);
362: intake.removeAll();
363: ScarabRequestTool scarabR = getScarabRequestTool(context);
364: String templateId = data.getParameters()
365: .getString("templateId");
366: if (templateId != null && templateId.length() > 0) {
367: IssueType templateType = IssueManager.getInstance(
368: new Long(templateId)).getIssueType();
369: setTarget(data, scarabR.getNextEntryTemplate(templateType
370: .getIssueTypeForTemplateType()));
371: ReportIssue.cleanOutStaleIssue(data, context);
372: }
373: }
374:
375: public void doSave(RunData data, TemplateContext context)
376: throws Exception {
377: doEditvalues(data, context);
378: doEdittemplateinfo(data, context);
379: }
380:
381: private boolean checkForDupes(IssueTemplateInfo template,
382: String newName, ScarabUser user, Issue issueTemplate)
383: throws Exception {
384: boolean areThereDupes = false;
385: Module module = issueTemplate.getModule();
386: List prevTemplates = IssueTemplateInfoPeer.getUserTemplates(
387: user, module, issueTemplate.getIssueType()
388: .getIssueTypeForTemplateType());
389: if (template.getScopeId().equals(Scope.MODULE__PK)) {
390: prevTemplates.addAll(IssueTemplateInfoPeer
391: .getModuleTemplates(module));
392: }
393: if (prevTemplates != null && !prevTemplates.isEmpty()) {
394: Long pk = template.getIssueId();
395: for (Iterator i = prevTemplates.iterator(); i.hasNext()
396: && !areThereDupes;) {
397: IssueTemplateInfo t = (IssueTemplateInfo) i.next();
398: areThereDupes = ((pk == null || !pk.equals(t
399: .getIssueId())) && newName.trim().toLowerCase()
400: .equals(t.getName().trim().toLowerCase()));
401: }
402: }
403: return areThereDupes;
404: }
405:
406: /**
407: Overrides base class.
408: */
409: public void doDone(RunData data, TemplateContext context)
410: throws Exception {
411: boolean success = doEdittemplateinfo(data, context);
412: if (success) {
413: doEditvalues(data, context);
414: doCancel(data, context);
415: }
416: }
417: }
|