0001: package org.tigris.scarab.actions;
0002:
0003: /* ================================================================
0004: * Copyright (c) 2000-2002 CollabNet. All rights reserved.
0005: *
0006: * Redistribution and use in source and binary forms, with or without
0007: * modification, are permitted provided that the following conditions are
0008: * met:
0009: *
0010: * 1. Redistributions of source code must retain the above copyright
0011: * notice, this list of conditions and the following disclaimer.
0012: *
0013: * 2. Redistributions in binary form must reproduce the above copyright
0014: * notice, this list of conditions and the following disclaimer in the
0015: * documentation and/or other materials provided with the distribution.
0016: *
0017: * 3. The end-user documentation included with the redistribution, if
0018: * any, must include the following acknowlegement: "This product includes
0019: * software developed by Collab.Net <http://www.Collab.Net/>."
0020: * Alternately, this acknowlegement may appear in the software itself, if
0021: * and wherever such third-party acknowlegements normally appear.
0022: *
0023: * 4. The hosted project names must not be used to endorse or promote
0024: * products derived from this software without prior written
0025: * permission. For written permission, please contact info@collab.net.
0026: *
0027: * 5. Products derived from this software may not use the "Tigris" or
0028: * "Scarab" names nor may "Tigris" or "Scarab" appear in their names without
0029: * prior written permission of Collab.Net.
0030: *
0031: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0032: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
0033: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
0034: * IN NO EVENT SHALL COLLAB.NET OR ITS CONTRIBUTORS BE LIABLE FOR ANY
0035: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
0036: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
0037: * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0038: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
0039: * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
0040: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
0041: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0042: *
0043: * ====================================================================
0044: *
0045: * This software consists of voluntary contributions made by many
0046: * individuals on behalf of Collab.Net.
0047: */
0048:
0049: import java.util.ArrayList;
0050: import java.util.HashMap;
0051: import java.util.Hashtable;
0052: import java.util.Iterator;
0053: import java.util.List;
0054: import java.util.Map;
0055:
0056: import org.apache.commons.lang.StringUtils;
0057: import org.apache.fulcrum.intake.Intake;
0058: import org.apache.fulcrum.intake.model.Field;
0059: import org.apache.fulcrum.intake.model.Group;
0060: import org.apache.fulcrum.parser.ParameterParser;
0061: import org.apache.fulcrum.parser.StringValueParser;
0062: import org.apache.torque.TorqueException;
0063: import org.apache.turbine.RunData;
0064: import org.apache.turbine.TemplateContext;
0065: import org.apache.turbine.Turbine;
0066: import org.tigris.scarab.actions.base.RequireLoginFirstAction;
0067: import org.tigris.scarab.om.Attribute;
0068: import org.tigris.scarab.om.AttributeManager;
0069: import org.tigris.scarab.om.AttributeOption;
0070: import org.tigris.scarab.om.AttributeOptionManager;
0071: import org.tigris.scarab.om.AttributeType;
0072: import org.tigris.scarab.om.AttributeValue;
0073: import org.tigris.scarab.om.IssueType;
0074: import org.tigris.scarab.om.IssueTypeManager;
0075: import org.tigris.scarab.om.MITList;
0076: import org.tigris.scarab.om.MITListManager;
0077: import org.tigris.scarab.om.Module;
0078: import org.tigris.scarab.om.ModuleManager;
0079: import org.tigris.scarab.om.Query;
0080: import org.tigris.scarab.om.QueryPeer;
0081: import org.tigris.scarab.om.RModuleUserAttribute;
0082: import org.tigris.scarab.om.ScarabUser;
0083: import org.tigris.scarab.om.Scope;
0084: import org.tigris.scarab.services.security.ScarabSecurity;
0085: import org.tigris.scarab.tools.ScarabLocalizationTool;
0086: import org.tigris.scarab.tools.ScarabRequestTool;
0087: import org.tigris.scarab.tools.localization.L10NKeySet;
0088: import org.tigris.scarab.tools.localization.L10NMessage;
0089: import org.tigris.scarab.util.IteratorWithSize;
0090: import org.tigris.scarab.util.Log;
0091: import org.tigris.scarab.util.ScarabConstants;
0092: import org.tigris.scarab.util.ScarabUtil;
0093: import org.tigris.scarab.util.export.ExportFormat;
0094: import org.tigris.scarab.util.word.IssueSearch;
0095: import org.tigris.scarab.util.word.IssueSearchFactory;
0096:
0097: /**
0098: * This class is responsible for searching.
0099: *
0100: * @author <a href="mailto:jmcnally@collab.net">John D. McNally</a>
0101: * @author <a href="mailto:elicia@collab.net">Elicia David</a>
0102: * @author <a href="mailto:jon@collab.net">Jon S. Stevens</a>
0103: * @version $Id: Search.java 10379 2006-12-11 00:37:12Z dabbous $
0104: */
0105: public class Search extends RequireLoginFirstAction {
0106: private static final String ADD_USER = "add_user";
0107: private static final String ADD_USER_BY_USERNAME = "add_user_by_username";
0108: private static final String SELECTED_USER = "select_user";
0109: private static final String USER_LIST = "user_list";
0110: private static final String ANY = "any";
0111: private static final String CREATED_BY = "created_by";
0112:
0113: private static final String OUTPUT_FORMAT = "output";
0114: private static final String WEB_OUTPUT = "web";
0115: private static final String FEED_OUTPUT = "feed";
0116:
0117: ScarabLocalizationTool l10n;
0118: ScarabRequestTool scarabR;
0119: Intake intake;
0120: ParameterParser params;
0121: ScarabUser user;
0122:
0123: /**
0124: *
0125: */
0126: public void doPerform(RunData data, TemplateContext context)
0127: throws Exception {
0128: setup(data, context);
0129: IteratorWithSize queryResults = scarabR
0130: .getCurrentSearchResults();
0131: if (queryResults != null && queryResults.hasNext()) {
0132: context.put("queryResults", queryResults);
0133: String next = ScarabUtil.findValue(data, "next");
0134: if (StringUtils.isNotEmpty(ScarabUtil.findValue(data,
0135: ExportFormat.KEY_NAME))) {
0136: // Send to the IssueListExport screen (which actually
0137: // has no corresponding Velocity template).
0138: setTarget(data, "IssueListExport.vm");
0139: } else if (StringUtils.isNotEmpty(next)) {
0140: // Redirect to View, Assign, or Move/Copy
0141: List issueIds = null;
0142: ScarabUser user = (ScarabUser) data.getUser();
0143: if (next.indexOf("All") > -1) {
0144: // all issues are selected
0145: issueIds = getAllIssueIds(data);
0146: } else {
0147: // get issues select by user
0148: issueIds = getSelected(data);
0149: }
0150:
0151: if (issueIds.size() < 1) {
0152: scarabR.setAlertMessage(L10NKeySet.SelectIssues);
0153: return;
0154: }
0155:
0156: List modules = ModuleManager
0157: .getInstancesFromIssueList(scarabR
0158: .getIssues(issueIds));
0159: if (next.indexOf("assign") > -1) {
0160: if (user.hasPermission(
0161: ScarabSecurity.ISSUE__ASSIGN, modules)) {
0162: if (issueIds.size() <= ScarabConstants.ISSUE_MAX_ASSIGN) {
0163: scarabR.resetAssociatedUsers();
0164: setTarget(data, "AssignIssue.vm");
0165: } else {
0166: L10NMessage msg = new L10NMessage(
0167: L10NKeySet.IssueLimitExceeded,
0168: String
0169: .valueOf(ScarabConstants.ISSUE_MAX_ASSIGN));
0170: scarabR.setAlertMessage(msg);
0171: return;
0172: }
0173: } else {
0174: scarabR.setAlertMessage(NO_PERMISSION_MESSAGE);
0175: return;
0176: }
0177: } else if (next.indexOf("view") > -1) {
0178: if (user.hasPermission(ScarabSecurity.ISSUE__VIEW,
0179: modules)) {
0180: if (issueIds.size() <= ScarabConstants.ISSUE_MAX_VIEW) {
0181: setTarget(data, "ViewIssueLong.vm");
0182: } else {
0183: L10NMessage msg = new L10NMessage(
0184: L10NKeySet.IssueLimitExceeded,
0185: String
0186: .valueOf(ScarabConstants.ISSUE_MAX_VIEW));
0187: scarabR.setAlertMessage(msg);
0188: return;
0189: }
0190: } else {
0191: scarabR.setAlertMessage(NO_PERMISSION_MESSAGE);
0192: return;
0193: }
0194: } else if (next.indexOf("copy") > -1) {
0195: if (user.hasPermission(ScarabSecurity.ISSUE__ENTER,
0196: modules)) {
0197: if (issueIds.size() <= ScarabConstants.ISSUE_MAX_COPY) {
0198: data.getParameters().add("mv_0rb", "copy");
0199: setTarget(data, "MoveIssue.vm");
0200: } else {
0201: L10NMessage msg = new L10NMessage(
0202: L10NKeySet.IssueLimitExceeded,
0203: String
0204: .valueOf(ScarabConstants.ISSUE_MAX_COPY));
0205: scarabR.setAlertMessage(msg);
0206: return;
0207: }
0208: } else {
0209: scarabR.setAlertMessage(NO_PERMISSION_MESSAGE);
0210: }
0211: } else if (next.indexOf("move") > -1) {
0212: if (user.hasPermission(ScarabSecurity.ISSUE__MOVE,
0213: modules)) {
0214: if (issueIds.size() <= ScarabConstants.ISSUE_MAX_MOVE) {
0215: data.getParameters().add("mv_0rb", "move");
0216: setTarget(data, "MoveIssue.vm");
0217: } else {
0218: L10NMessage msg = new L10NMessage(
0219: L10NKeySet.IssueLimitExceeded,
0220: String
0221: .valueOf(ScarabConstants.ISSUE_MAX_MOVE));
0222: scarabR.setAlertMessage(msg);
0223: return;
0224: }
0225: } else {
0226: scarabR.setAlertMessage(NO_PERMISSION_MESSAGE);
0227: }
0228: }
0229: } else {
0230: String template = data.getParameters().getString(
0231: ScarabConstants.NEXT_TEMPLATE,
0232: getIssueListTarget());
0233: setTarget(data, template);
0234: }
0235: }
0236: }
0237:
0238: /**
0239: * Saves the query string for the logged-in user, and performs the
0240: * default action of {@link #doPerform}.
0241: */
0242: public void doSearch(RunData data, TemplateContext context)
0243: throws Exception {
0244: setup(data, context);
0245: String queryString = getQueryString(data);
0246: user.setMostRecentQuery(queryString);
0247:
0248: doPerform(data, context);
0249: }
0250:
0251: /**
0252: Redirects to form to save the query. May redirect to Login page.
0253: */
0254: public void doRedirecttosavequery(RunData data,
0255: TemplateContext context) throws Exception {
0256: setup(data, context);
0257: if (data.getParameters().getString("refine") != null) {
0258: user.setMostRecentQuery(getQueryString(data));
0259: }
0260:
0261: if (scarabR
0262: .hasPermission(ScarabSecurity.USER__EDIT_PREFERENCES)) {
0263: setTarget(data, "SaveQuery.vm");
0264: } else {
0265: scarabR.setAlertMessage(NO_PERMISSION_MESSAGE);
0266: }
0267: }
0268:
0269: public void doRedirecttocrossmodulelist(RunData data,
0270: TemplateContext context) throws Exception {
0271: data.getParameters().setString("queryString",
0272: getQueryString(data));
0273: setTarget(data, "IssueTypeList.vm");
0274: }
0275:
0276: /**
0277: Saves query.
0278: */
0279: public void doSavequery(RunData data, TemplateContext context)
0280: throws Exception {
0281: setup(data, context);
0282:
0283: if (!scarabR
0284: .hasPermission(ScarabSecurity.USER__EDIT_PREFERENCES)) {
0285: scarabR.setAlertMessage(NO_PERMISSION_MESSAGE);
0286: return;
0287: }
0288:
0289: Module module = scarabR.getCurrentModule();
0290: Query query = scarabR.getQuery();
0291: Group queryGroup = intake.get("Query", query.getQueryKey());
0292:
0293: Field name = queryGroup.get("Name");
0294: name.setRequired(true);
0295: data.getParameters().setString("queryString",
0296: getQueryString(data));
0297:
0298: if (intake.isAllValid()) {
0299: queryGroup.setProperties(query);
0300: query.setScarabUser(user);
0301: MITList currentList = user.getCurrentMITList();
0302: if (currentList == null) {
0303: scarabR.setAlertMessage(L10NKeySet.NoIssueTypeList);
0304: return;
0305: } else {
0306: //
0307: // Get hold of all the attributes that apply to
0308: // this list. We will have to copy them manually
0309: // to the new list because MITList.copy() won't
0310: // do it for us.
0311: //
0312: List commonAttributes = currentList
0313: .getCommonRModuleUserAttributes();
0314:
0315: // associate the query with a new list, the current
0316: // implementation does not allow for multiple queries to
0317: // work from the same MITList and this guarantees they
0318: // will not accidently be linked.
0319: currentList = currentList.copy();
0320: if (currentList.isModifiable()) {
0321: currentList.setName(null);
0322: }
0323:
0324: //
0325: // Copy the attributes from the original list
0326: // to the new one.
0327: //
0328: for (Iterator iter = commonAttributes.iterator(); iter
0329: .hasNext();) {
0330: RModuleUserAttribute attr = (RModuleUserAttribute) iter
0331: .next();
0332:
0333: //
0334: // When we copy the attribute, we don't actually
0335: // want to keep the list ID because that refers
0336: // to the old list rather than the new one. So
0337: // we just clear it - when the list is saved the
0338: // correct list ID will automatically be set for
0339: // the attribute.
0340: //
0341: RModuleUserAttribute newAttr = attr.copy();
0342: newAttr.setListId(null);
0343: newAttr.setUserId(user.getUserId());
0344: currentList.addRModuleUserAttribute(newAttr);
0345: }
0346:
0347: //
0348: // Update the query to use the new MIT list.
0349: //
0350: query.setMITList(currentList);
0351: if (!currentList.isSingleModule()) {
0352: query.setModule(null);
0353: query.setScopeId(Scope.PERSONAL__PK);
0354: }
0355: }
0356:
0357: ScarabUser[] userList = module
0358: .getUsers(ScarabSecurity.ITEM__APPROVE);
0359: if (checkForDupes(query, user, module)) {
0360: scarabR.setAlertMessage(L10NKeySet.DuplicateQueryName);
0361: } else if (Scope.MODULE__PK.equals(query.getScopeId())
0362: && user.hasPermission(ScarabSecurity.ITEM__APPROVE,
0363: module)
0364: && (userList == null || userList.length == 0)) {
0365: L10NMessage msg = new L10NMessage(
0366: L10NKeySet.NoApproverAvailable, module
0367: .getName());
0368: scarabR.setAlertMessage(msg);
0369: } else {
0370: try {
0371: query.saveAndSendEmail(user, module, context);
0372: } catch (Exception e) {
0373: L10NMessage msg = new L10NMessage(
0374: L10NKeySet.ExceptionGeneral, e);
0375: scarabR.setAlertMessage(msg);
0376: }
0377: scarabR.resetSelectedUsers();
0378: if (query.canEdit(user)) {
0379: scarabR.setConfirmMessage(DEFAULT_MSG);
0380: } else {
0381: L10NMessage msg = new L10NMessage(
0382: L10NKeySet.NotifyPendingApproval,
0383: L10NKeySet.Query);
0384: scarabR.setInfoMessage(msg);
0385: //scarabR.setInfoMessage(
0386: // l10n.format("NotifyPendingApproval",
0387: // l10n.get("Query").toLowerCase()));
0388: }
0389: setTarget(data, "QueryList.vm");
0390: }
0391: } else {
0392: scarabR.setAlertMessage(ERROR_MESSAGE);
0393: }
0394: }
0395:
0396: public boolean doEditqueryinfo(RunData data, TemplateContext context)
0397: throws Exception {
0398: setup(data, context);
0399: boolean success = false;
0400:
0401: Module module = scarabR.getCurrentModule();
0402: Query query = scarabR.getQuery();
0403: Group queryGroup = intake.get("Query", query.getQueryKey());
0404: queryGroup.get("Name").setRequired(true);
0405: if (intake.isAllValid()) {
0406: queryGroup.setProperties(query);
0407: if (checkForDupes(query, user, module)) {
0408: scarabR.setAlertMessage(L10NKeySet.DuplicateQueryName);
0409: } else {
0410: query.saveAndSendEmail(user, module, context);
0411: success = true;
0412: if (query.canEdit(user)) {
0413: scarabR.setConfirmMessage(L10NKeySet.QueryModified);
0414: } else {
0415: L10NMessage msg = new L10NMessage(
0416: L10NKeySet.NotifyPendingApproval,
0417: L10NKeySet.Query);
0418: scarabR.setInfoMessage(msg);
0419: //scarabR.setInfoMessage(
0420: // l10n.format("NotifyPendingApproval",
0421: // l10n.get("Query").toLowerCase()));
0422: setTarget(data, data.getParameters().getString(
0423: ScarabConstants.CANCEL_TEMPLATE));
0424: }
0425:
0426: }
0427: } else {
0428: scarabR.setAlertMessage(ERROR_MESSAGE);
0429: }
0430: return success;
0431: }
0432:
0433: public void doPreparequery(RunData data, TemplateContext context)
0434: throws Exception {
0435: setup(data, context);
0436: Query query = scarabR.getQuery();
0437: user.setCurrentMITList(query.getMITList());
0438: /* TODO! It would be better if the query could be viewed or
0439: edited without having to pass the query data via request parameters
0440: as would be done with the code below, but it caused a few bugs like
0441: losing users and maybe the mitlist, so revisit this later.
0442: user.setMostRecentQuery(query.getValue());
0443: */
0444: user.setMostRecentQuery(getQueryString(data));
0445: scarabR.resetSelectedUsers();
0446: }
0447:
0448: /**
0449: Edits the stored query.
0450: */
0451: public void doEditstoredquery(RunData data, TemplateContext context)
0452: throws Exception {
0453: setup(data, context);
0454:
0455: Query query = scarabR.getQuery();
0456: String newValue = getQueryString(data);
0457: query.setValue(newValue);
0458: query.saveAndSendEmail((ScarabUser) data.getUser(), scarabR
0459: .getCurrentModule(), context);
0460: scarabR.resetSelectedUsers();
0461: user.setMostRecentQuery(newValue);
0462: }
0463:
0464: /**
0465: Runs the stored story.
0466: */
0467: public void doRunstoredquery(RunData data, TemplateContext context)
0468: throws Exception {
0469: setup(data, context);
0470: // Set current query to the stored query
0471: Query query = scarabR.getQuery();
0472: MITList mitList = query.getMITList();
0473: user.setCurrentMITList(mitList);
0474: if (mitList != null) {
0475: mitList.setScarabUser(user);
0476: }
0477: user.setMostRecentQuery(query.getValue());
0478:
0479: //
0480: // Add 'sortColumn', 'sortPolarity' and 'resultsPerPage'
0481: // to the RunData parameters. This ensures that when the
0482: // user runs a saved query, the resulting issue list is
0483: // displayed with that query's settings.
0484: //
0485: StringValueParser parser = new StringValueParser();
0486: parser.parse(query.getValue(), '&', '=', true);
0487:
0488: if (parser.containsKey("resultsperpage")) {
0489: data.getParameters().add("resultsperpage",
0490: parser.getInt("resultsperpage"));
0491: }
0492:
0493: if (parser.containsKey("searchsai")) {
0494: data.getParameters().add("sortColumn",
0495: parser.getInt("searchsai"));
0496: }
0497:
0498: if (parser.containsKey("searchsp")) {
0499: data.getParameters().add("sortPolarity",
0500: parser.getString("searchsp"));
0501: }
0502:
0503: setTarget(data, getIssueListTarget());
0504: }
0505:
0506: /**
0507: * This method handles clicking the Go button in the SearchNav.vm
0508: * file. First it checks to see if the select box passed in a number
0509: * or a string. If it is a number, then we run the stored query
0510: * assuming the number is the query id. Else, we assume it is a
0511: * string and that is our template to redirect to.
0512: */
0513: public void doSelectquery(RunData data, TemplateContext context)
0514: throws Exception {
0515: setup(data, context);
0516: String go = data.getParameters().getString("go");
0517:
0518: if (go != null && go.length() > 0) {
0519: // if the string is a number, then execute
0520: // doRunstoredquery()
0521: if (StringUtils.isNumeric(go)) {
0522: data.getParameters().setString("queryId", go);
0523: doRunstoredquery(data, context);
0524: } else if (go.startsWith("newQuery")) {
0525: // do this to load last mitlist
0526: user.getMostRecentQuery();
0527: if (go.endsWith("IT")) {
0528: user.setCurrentMITList(null);
0529: }
0530: // reset selected users map
0531: scarabR.resetSelectedUsers();
0532: setTarget(data, user.getQueryTarget());
0533: } else if (go.equals("mostRecent")) {
0534: setTarget(data, getIssueListTarget());
0535: } else if (go.equals("myIssuesThisModule")) {
0536: Module module = user.getCurrentModule();
0537: user
0538: .setCurrentMITList(MITListManager
0539: .getSingleModuleAllIssueTypesList(
0540: module, user));
0541:
0542: String userId = user.getQueryKey();
0543: StringBuffer sb = new StringBuffer(26 + 2 * userId
0544: .length());
0545: String query = sb.append("&user_list=").append(userId)
0546: .append("&user_attr_").append(userId).append(
0547: "=any").toString();
0548: user.setMostRecentQuery(query);
0549: setTarget(data, getIssueListTarget());
0550: } else if (go.equals("myIssuesAllModules")) {
0551: user.setCurrentMITList(MITListManager
0552: .getAllModulesAllIssueTypesList(user));
0553:
0554: String userId = user.getQueryKey();
0555: StringBuffer sb = new StringBuffer(26 + 2 * userId
0556: .length());
0557: String query = sb.append("&user_list=").append(userId)
0558: .append("&user_attr_").append(userId).append(
0559: "=any").toString();
0560: user.setMostRecentQuery(query);
0561: setTarget(data, getIssueListTarget());
0562: } else if (go.equals("quickSearch")) {
0563: String searchString = data.getParameters().getString(
0564: "searchString");
0565: if (searchString == null || searchString.equals("")) {
0566: scarabR
0567: .setAlertMessage(L10NKeySet.QueryParserError);
0568: } else {
0569: Module module = user.getCurrentModule();
0570: MITList mitList = MITListManager
0571: .getSingleModuleAllIssueTypesList(module,
0572: user);
0573: user.setCurrentMITList(mitList);
0574:
0575: Map attributeMap = new Hashtable();
0576: List attributes = module.getAllAttributes();
0577: for (int aindex = 0; aindex < attributes.size(); aindex++) {
0578: Attribute attribute = (Attribute) attributes
0579: .get(aindex);
0580: AttributeType type = attribute
0581: .getAttributeType();
0582: String typeName = type.getName();
0583: if (typeName.equals("string")
0584: || typeName.equals("long-string")) {
0585: if (attribute.isTextAttribute()) {
0586: Integer id = attribute.getAttributeId();
0587: if (attributeMap.get(id) == null) {
0588: attributeMap.put(id, attribute);
0589: }
0590: }
0591: }
0592: }
0593: quickSearch(searchString, attributeMap, user,
0594: context);
0595: }
0596: setTarget(data, getIssueListTarget());
0597: } else if (go.equals("privateQueries")
0598: || go.equals("publicQueries")) {
0599: setTarget(data, "QueryList.vm");
0600: } else {
0601: setTarget(data, go);
0602: }
0603: if (go.equals("myIssues") || go.equals("mostRecent")) {
0604: IteratorWithSize searchResults = null;
0605: try {
0606: searchResults = scarabR.getCurrentSearchResults();
0607: } catch (java.lang.IllegalArgumentException e) {
0608: // Swallow this exception.
0609: Log.get().debug("", e);
0610: }
0611: if (searchResults != null && searchResults.size() > 0) {
0612: context.put("issueList", searchResults);
0613: }
0614: }
0615: } else {
0616: // set the next template
0617: String nextTemplate = data.getParameters().getString(
0618: ScarabConstants.NEXT_TEMPLATE,
0619: Turbine.getConfiguration().getString(
0620: "template.homepage", "Index.vm"));
0621: setTarget(data, nextTemplate);
0622: }
0623: }
0624:
0625: /**
0626: * @param attributeMap
0627: * @return
0628: */
0629: private void quickSearch(String searchString, Map attributeMap,
0630: ScarabUser user, TemplateContext context) {
0631: String queryPart;
0632:
0633: Iterator iter = attributeMap.keySet().iterator();
0634: queryPart = "";
0635: while (iter.hasNext()) {
0636: Integer id = (Integer) iter.next();
0637: queryPart += "&attv__" + id + "val=" + searchString;
0638: }
0639:
0640: processSearch(queryPart, user, context);
0641: }
0642:
0643: private void processSearch(String queryPart, ScarabUser user,
0644: TemplateContext context) {
0645: String query;
0646:
0647: String userId = user.getQueryKey();
0648:
0649: String queryStart = "&user_attr_" + userId + "=any"
0650: + "&intake-grp=attv" + "&intake-grp=search"
0651: + "&searchsp=asc" + "&searchtype=advanced"
0652: + "&searchallattributes=true";
0653:
0654: final String queryEnd = "&searchsctoi=0" + "&resultsperpage="
0655: + ScarabConstants.ISSUE_MAX_VIEW + "&searchscfoi=0";
0656: query = queryStart;
0657: query += queryPart;
0658: query += queryEnd;
0659:
0660: user.setMostRecentQuery(query.toLowerCase());
0661:
0662: IteratorWithSize searchResults = null;
0663: try {
0664: searchResults = scarabR.getCurrentSearchResults();
0665: } catch (java.lang.IllegalArgumentException e) {
0666: // Swallow this exception.
0667: Log.get().debug("", e);
0668: }
0669: if (searchResults != null && searchResults.size() > 0) {
0670: context.put("issueList", searchResults);
0671: }
0672: }
0673:
0674: private void attributeSearch(String optionValue,
0675: AttributeValue attributeValue, ScarabUser user,
0676: TemplateContext context) {
0677: Integer id = (attributeValue.getAttributeId());
0678: String queryPart = "&attv__" + id + "val=" + optionValue;
0679: processSearch(queryPart, user, context);
0680: }
0681:
0682: /**
0683: redirects to AdvancedQuery.
0684: */
0685: public void doRefinequery(RunData data, TemplateContext context)
0686: throws Exception {
0687: context.put("refine", "true");
0688: setTarget(data, "AdvancedQuery.vm");
0689: }
0690:
0691: /**
0692: Overrides base class.
0693: */
0694: public void doDone(RunData data, TemplateContext context)
0695: throws Exception {
0696: boolean success = doEditqueryinfo(data, context);
0697: if (success) {
0698: doEditstoredquery(data, context);
0699: doCancel(data, context);
0700: }
0701: }
0702:
0703: /**
0704: * @return The search string used to perform the query. (Does
0705: * <i>not</i> refer to the CGI context of the term "query
0706: * string".)
0707: */
0708: public static String getQueryString(RunData data) throws Exception {
0709: String queryString = data.getParameters().getString(
0710: "queryString");
0711: if (queryString == null) {
0712: StringBuffer buf = new StringBuffer();
0713: Object[] keys = data.getParameters().getKeys();
0714: for (int i = 0; i < keys.length; i++) {
0715: String key = keys[i].toString();
0716: if (key.startsWith("attv") || key.startsWith("search")
0717: || key.startsWith("intake")
0718: || key.startsWith("user_attr")
0719: || key.startsWith("user_list")
0720: || key.startsWith("results")
0721: || "format".equalsIgnoreCase(key)) {
0722: String[] values = data.getParameters().getStrings(
0723: key);
0724: for (int j = 0; j < values.length; j++) {
0725: String value = values[j];
0726: if (StringUtils.isNotEmpty(value)) {
0727: buf.append('&').append(key);
0728: buf.append('=').append(
0729: ScarabUtil.urlEncode(value));
0730: }
0731: }
0732: }
0733: }
0734:
0735: queryString = (buf.length() == 0 ? ((ScarabUser) data
0736: .getUser()).getMostRecentQuery() : buf.toString());
0737: }
0738: if (queryString == null) {
0739: queryString = "";
0740: }
0741: return queryString.toLowerCase();
0742: }
0743:
0744: /**
0745: Check for duplicate query names.
0746: A user cannot create a personal query with the same name as another one
0747: of their personal queries.
0748: A user cannot create a module-level query with the same name
0749: as another module-level query in the same module.
0750: */
0751: private boolean checkForDupes(Query query, ScarabUser user,
0752: Module module) throws Exception {
0753: boolean areThereDupes = false;
0754: List prevQueries = new ArrayList();
0755: if (query.getScopeId().equals(Scope.MODULE__PK)) {
0756: prevQueries.addAll(QueryPeer.getModuleQueries(module));
0757: } else {
0758: // Add personal queries only, not all module-level queries created
0759: // by this user.
0760: for (Iterator i = QueryPeer.getUserQueries(user).iterator(); i
0761: .hasNext();) {
0762: Query q = (Query) i.next();
0763: if (q.getModule() == null) {
0764: prevQueries.add(q);
0765: }
0766: }
0767: }
0768: if (prevQueries != null && !prevQueries.isEmpty()) {
0769: Long pk = query.getQueryId();
0770: String name = query.getName();
0771: for (Iterator i = prevQueries.iterator(); i.hasNext()
0772: && !areThereDupes;) {
0773: Query q = (Query) i.next();
0774: areThereDupes = (pk == null || !pk.equals(q
0775: .getQueryId()))
0776: && name.trim().toLowerCase().equals(
0777: q.getName().trim().toLowerCase());
0778: }
0779: }
0780: return areThereDupes;
0781: }
0782:
0783: /**
0784: Retrieves list of all issue id's and puts in the context.
0785: */
0786: private List getAllIssueIds(RunData data) {
0787: List newIssueIdList = new ArrayList();
0788: ParameterParser pp = data.getParameters();
0789: String[] allIssueIds = pp.getStrings("all_issue_ids");
0790: if (allIssueIds != null) {
0791: while (pp.containsKey("issue_ids")) {
0792: pp.remove("issue_ids");
0793: }
0794: for (int i = 0; i < allIssueIds.length; i++) {
0795: pp.add("issue_ids", allIssueIds[i]);
0796: newIssueIdList.add(allIssueIds[i]);
0797: }
0798: }
0799: return newIssueIdList;
0800: }
0801:
0802: public void doGetissues(RunData data, TemplateContext context)
0803: throws TorqueException {
0804: try {
0805: setup(data, context);
0806: } catch (Exception e) {
0807: // no module selected
0808: return;
0809: }
0810:
0811: ParameterParser pp = data.getParameters();
0812: Module module = user.getCurrentModule();
0813:
0814: MITList mitList;
0815: int issueTypeId = pp.getInt("issueType");
0816: if (issueTypeId > 0) {
0817: // search only within specidied issueType
0818: IssueType issueType = IssueTypeManager
0819: .getInstance(new Integer(issueTypeId));
0820: mitList = MITListManager.getSingleItemList(module,
0821: issueType, user);
0822: } else {
0823: // search all issueTypes in current module
0824: mitList = MITListManager.getSingleModuleAllIssueTypesList(
0825: module, user);
0826: }
0827:
0828: user.setCurrentMITList(mitList);
0829: int optionId = pp.getInt("option");
0830:
0831: if (optionId > 0) {
0832: // search only issues with given attribute set to given value
0833: Integer oid = new Integer(optionId);
0834: AttributeOption ao = AttributeOptionManager
0835: .getInstance(oid);
0836: Integer attId = ao.getAttributeId();
0837: Attribute attribute = AttributeManager.getInstance(attId);
0838:
0839: AttributeValue av = AttributeValue.getNewInstance(
0840: attribute, null);
0841: String aoname = ao.getName();
0842: attributeSearch(aoname, av, user, context);
0843: } else {
0844: // search all issues in current MITList (see MITList initializatoin above)
0845: processSearch("", user, context);
0846: }
0847:
0848: return;
0849: }
0850:
0851: /**
0852: Retrieves list of selected issue id's and puts in the context.
0853: */
0854: private List getSelected(RunData data) {
0855: List newIssueIdList = new ArrayList();
0856: ParameterParser pp = data.getParameters();
0857: String[] selectedIds = pp.getStrings("issue_ids");
0858: if (selectedIds != null) {
0859: while (pp.containsKey("issue_ids")) {
0860: pp.remove("issue_ids");
0861: }
0862: for (int i = 0; i < selectedIds.length; i++) {
0863: pp.add("issue_ids", selectedIds[i]);
0864: newIssueIdList.add(selectedIds[i]);
0865: }
0866: }
0867: return newIssueIdList;
0868: }
0869:
0870: public void doGotoeditlist(RunData data, TemplateContext context)
0871: throws Exception {
0872: setup(data, context);
0873: Map userMap = user.getSelectedUsersMap();
0874: if (userMap == null || userMap.size() == 0) {
0875: userMap = new HashMap();
0876: loadUsersFromUserList(data, userMap);
0877: }
0878: data.getParameters().setString(ScarabConstants.CANCEL_TEMPLATE,
0879: getCurrentTemplate(data));
0880: user.setMostRecentQuery(getQueryString(data));
0881: IssueSearch search = scarabR.getPopulatedSearch();
0882: if (search != null) {
0883: setTarget(data, "UserList.vm");
0884: IssueSearchFactory.INSTANCE.notifyDone();
0885: }
0886: }
0887:
0888: /**
0889: * Adds users from temporary working list.
0890: */
0891: public void doAddusers(RunData data, TemplateContext context)
0892: throws Exception {
0893: setup(data, context);
0894:
0895: Map userMap = user.getSelectedUsersMap();
0896: if (userMap == null) {
0897: userMap = new HashMap();
0898: }
0899: String[] userIds = params.getStrings(ADD_USER);
0900: if (userIds != null && userIds.length > 0) {
0901: for (int i = 0; i < userIds.length; i++) {
0902: String userId = userIds[i];
0903: String[] attrIds = params.getStrings("user_attr_"
0904: + userId);
0905: if (attrIds != null) {
0906: for (int j = 0; j < attrIds.length; j++) {
0907: addAttributeToMap(userMap, userId, attrIds[j],
0908: context);
0909: }
0910: }
0911: }
0912: user.setSelectedUsersMap(userMap);
0913: scarabR
0914: .setConfirmMessage(L10NKeySet.SelectedUsersWereAdded);
0915: } else {
0916: scarabR.setAlertMessage(L10NKeySet.NoUsersSelected);
0917: }
0918: }
0919:
0920: /**
0921: Adds user to the search form.
0922: */
0923: public void doAdduserbyusername(RunData data,
0924: TemplateContext context) throws Exception {
0925: setup(data, context);
0926:
0927: String userName = params.getString(ADD_USER_BY_USERNAME);
0928: String attrId = params.getString("add_user_attr");
0929:
0930: Map userMap = user.getSelectedUsersMap();
0931: if (userMap == null || userMap.size() == 0) {
0932: userMap = new HashMap();
0933: loadUsersFromUserList(data, userMap);
0934: }
0935:
0936: ScarabUser newUser = scarabR.getUserByUserName(userName);
0937: boolean success = false;
0938: // we are only interested in users that can be assignees
0939: if (newUser != null) {
0940: MITList mitList = user.getCurrentMITList();
0941: List modules = mitList.getModules();
0942: if (ANY.equals(attrId)) {
0943: success = false;
0944: // check that the user has at least one applicable attribute
0945: for (Iterator i = mitList.getCommonUserAttributes()
0946: .iterator(); i.hasNext() && !success;) {
0947: success = newUser.hasPermission(((Attribute) i
0948: .next()).getPermission(), modules);
0949: }
0950: if (!success) {
0951: // check created by
0952: success = newUser.hasPermission(
0953: ScarabSecurity.ISSUE__ENTER, modules);
0954: }
0955: } else if (CREATED_BY.equals(attrId)) {
0956: success = newUser.hasPermission(
0957: ScarabSecurity.ISSUE__ENTER, modules);
0958: } else {
0959: try {
0960: Attribute attribute = scarabR
0961: .getAttribute(new Integer(attrId));
0962: success = newUser.hasPermission(attribute
0963: .getPermission(), modules);
0964: } catch (Exception e) {
0965: // don't allow adding the user
0966: success = false;
0967: Log.get().error(
0968: "Error trying to get user ," + userName
0969: + ", for a query. Attribute id = "
0970: + attrId, e);
0971: }
0972: }
0973: }
0974:
0975: if (success) {
0976: String userId = newUser.getUserId().toString();
0977: addAttributeToMap(userMap, userId, attrId, context);
0978: user.setSelectedUsersMap(userMap);
0979: scarabR
0980: .setConfirmMessage(L10NKeySet.SelectedUsersWereAdded);
0981: } else {
0982: scarabR.setAlertMessage(L10NKeySet.UserNotPossibleAssignee);
0983: }
0984: }
0985:
0986: private void addAttributeToMap(Map userMap, String userId,
0987: String attrId, TemplateContext context) {
0988: ScarabRequestTool scarabR = getScarabRequestTool(context);
0989: ScarabLocalizationTool l10n = getLocalizationTool(context);
0990: List attrIds = (List) userMap.get(userId);
0991: if (attrIds == null) {
0992: attrIds = new ArrayList(3);
0993: userMap.put(userId, attrIds);
0994: }
0995:
0996: if (ANY.equals(attrId)) {
0997: if (!attrIds.isEmpty()) {
0998: scarabR
0999: .setInfoMessage(L10NKeySet.AnyHasReplacedPreviousChoices);
1000: }
1001: attrIds.clear();
1002: }
1003:
1004: boolean isNew = true;
1005: for (Iterator i = attrIds.iterator(); i.hasNext() && isNew;) {
1006: Object oldAttrId = i.next();
1007: isNew = !ANY.equals(oldAttrId) && !oldAttrId.equals(attrId);
1008: }
1009:
1010: if (isNew) {
1011: attrIds.add(attrId);
1012: } else {
1013: scarabR
1014: .setInfoMessage(L10NKeySet.ChoiceAlreadyAccountedAny);
1015: }
1016: }
1017:
1018: /**
1019: * Removes users from temporary working list.
1020: */
1021: public void doRemoveusers(RunData data, TemplateContext context)
1022: throws Exception {
1023: setup(data, context);
1024:
1025: Map userMap = user.getSelectedUsersMap();
1026: if (userMap == null || userMap.size() == 0) {
1027: userMap = new HashMap();
1028: loadUsersFromUserList(data, userMap);
1029: }
1030:
1031: String[] userAttrIds = params.getStrings(SELECTED_USER);
1032: if (userAttrIds != null && userAttrIds.length > 0) {
1033: for (int i = 0; i < userAttrIds.length; i++) {
1034: String userAttrId = userAttrIds[i];
1035: int delimPos = userAttrId.indexOf('_');
1036: String userId = userAttrId.substring(0, delimPos);
1037: List currentAttrIds = (List) userMap.get(userId);
1038: if (currentAttrIds.size() == 1) {
1039: userMap.remove(userId);
1040: } else {
1041: currentAttrIds.remove(userAttrId
1042: .substring(delimPos + 1));
1043: }
1044: }
1045: user.setSelectedUsersMap(userMap);
1046: scarabR
1047: .setConfirmMessage(L10NKeySet.SelectedUsersWereRemoved);
1048: } else {
1049: scarabR.setAlertMessage(L10NKeySet.NoUsersSelected);
1050: }
1051: }
1052:
1053: /**
1054: * Changes the user attribute a user is associated with.
1055: */
1056: public void doUpdateusers(RunData data, TemplateContext context)
1057: throws Exception {
1058: setup(data, context);
1059:
1060: Map userMap = user.getSelectedUsersMap();
1061:
1062: String[] userAttrIds = params.getStrings(SELECTED_USER);
1063: if (userAttrIds != null && userAttrIds.length > 0) {
1064: for (int i = 0; i < userAttrIds.length; i++) {
1065: String userAttrId = userAttrIds[i];
1066: int delimPos = userAttrId.indexOf('_');
1067: String userId = userAttrId.substring(0, delimPos);
1068: String oldAttrId = userAttrId.substring(delimPos + 1);
1069: String newAttrId = params.getString("user_attr_"
1070: + userAttrId);
1071: if (!oldAttrId.equals(newAttrId)) {
1072: List currentAttrIds = (List) userMap.get(userId);
1073: if (ANY.equals(newAttrId)) {
1074: currentAttrIds.clear();
1075: currentAttrIds.add(ANY);
1076: } else {
1077: for (int j = currentAttrIds.size() - 1; j >= 0; j--) {
1078: if (currentAttrIds.get(j).equals(oldAttrId)) {
1079: currentAttrIds.set(j, newAttrId);
1080: break;
1081: }
1082: }
1083: }
1084: }
1085: }
1086: user.setSelectedUsersMap(userMap);
1087: scarabR
1088: .setConfirmMessage(L10NKeySet.SelectedUsersWereModified);
1089: } else {
1090: scarabR.setAlertMessage(L10NKeySet.NoUsersSelected);
1091: }
1092: }
1093:
1094: /**
1095: * In the case of a saved query, puts the saved query's users
1096: * Into the selected users map
1097: */
1098: public void loadUsersFromUserList(RunData data, Map userMap)
1099: throws Exception {
1100: ParameterParser params = data.getParameters();
1101: String[] userList = params.getStrings(USER_LIST);
1102: if (userList != null && userList.length > 0) {
1103: for (int i = 0; i < userList.length; i++) {
1104: String userId = userList[i];
1105: String[] attrIds = params.getStrings("user_attr_"
1106: + userId);
1107: if (attrIds != null) {
1108: for (int j = 0; j < attrIds.length; j++) {
1109: addAttributeToMap(userMap, userId, attrIds[j],
1110: getTemplateContext(data));
1111: }
1112: }
1113: }
1114: ((ScarabUser) data.getUser()).setSelectedUsersMap(userMap);
1115: }
1116: }
1117:
1118: public void doSetquerytarget(RunData data, TemplateContext context)
1119: throws Exception {
1120: setup(data, context);
1121:
1122: MITList mitlist = user.getCurrentMITList();
1123: if (mitlist != null && mitlist.isSingleModuleIssueType()) {
1124: user.setSingleIssueTypeQueryTarget(mitlist.getIssueType(),
1125: data.getTarget());
1126: } else {
1127:
1128: if (mitlist == null) {
1129: scarabR.setAlertMessage(L10NKeySet.NoIssueTypeList);
1130: } else {
1131: scarabR
1132: .setAlertMessage(L10NKeySet.IssueTypeListMoreThanOne);
1133: }
1134:
1135: Log
1136: .get()
1137: .warn(
1138: "Issue type list did not contain one and only one element.");
1139: }
1140: }
1141:
1142: private void setup(RunData data, TemplateContext context)
1143: throws Exception {
1144: l10n = getLocalizationTool(context);
1145: scarabR = getScarabRequestTool(context);
1146: intake = getIntakeTool(context);
1147: params = data.getParameters();
1148: user = (ScarabUser) data.getUser();
1149: }
1150:
1151: /**
1152: *
1153: * @param data
1154: * @param outputFormat Possible values: WEB_OUTPUT | FEED_OUTPUT
1155: */
1156: private String getIssueListTarget() {
1157: String outputFormat = this .params.getString(OUTPUT_FORMAT,
1158: WEB_OUTPUT);
1159: if (outputFormat.equals(FEED_OUTPUT)) {
1160: return "RSSIssueList.vm";
1161: } else {
1162: return "IssueList.vm";
1163: }
1164: }
1165:
1166: }
|