001: package org.tigris.scarab.om;
002:
003: /* ================================================================
004: * Copyright (c) 2000-2005 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.List;
050: import java.util.ArrayList;
051: import java.io.Serializable;
052: import org.apache.torque.TorqueException;
053: import org.apache.torque.util.Criteria;
054:
055: // Local classes
056: import org.tigris.scarab.om.Module;
057:
058: /**
059: * This is the QueryPeer class
060: *
061: * @author <a href="mailto:jmcnally@collab.net">John McNally</a>
062: * @version $Id: QueryPeer.java 10074 2006-04-27 22:26:31Z jorgeuriarte $
063: */
064: public class QueryPeer extends BaseQueryPeer {
065:
066: static final String GET_QUERIES = "getQueries";
067: static final String GET_USER_QUERIES = "getUserQueries";
068: static final String GET_MODULE_QUERIES = "getModuleQueries";
069: static final String QUERY_PEER = "QueryPeer";
070:
071: // query types
072: public static final String TYPE_ALL_USER = "allPrivate";
073: public static final String TYPE_PRIVATE = "private";
074: public static final String TYPE_GLOBAL = "global";
075: public static final String TYPE_ALL = "all";
076:
077: // sort columns
078: public static final String SORT_NAME = "name";
079: public static final String SORT_DESCRIPTION = "desc";
080: public static final String SORT_AVAILABILITY = "avail";
081: public static final String SORT_USER = "user";
082:
083: /**
084: * List of queries associated with the module or created by the user.
085: * valid type is private, global, or all.
086: * if issueType == null, ignore issue type, otherwise include queries
087: * that only use that issueType or use multiple issue types.
088: */
089: public static List getQueries(Module module, IssueType issueType,
090: ScarabUser user, String sortColumn, String sortPolarity,
091: String type) throws TorqueException {
092: List queries = null;
093: if (module == null || module.isGlobalModule()) {
094: queries = new ArrayList();
095: } else {
096: // FIXME: 4th element is ignored due to bug in torque
097: // not yet fixed in torque-3.0
098: Serializable[] key = { QUERY_PEER, GET_QUERIES, module,
099: null, issueType, user, sortColumn, sortPolarity,
100: type };
101: Object obj = QueryManager.getMethodResult().get(key);
102: if (obj == null) {
103:
104: Criteria crit = new Criteria()
105: .add(QueryPeer.DELETED, 0);
106:
107: Criteria.Criterion moduleCrit = crit.getNewCriterion(
108: QueryPeer.MODULE_ID, module.getModuleId(),
109: Criteria.EQUAL);
110: Criteria.Criterion crossModule = crit.getNewCriterion(
111: QueryPeer.MODULE_ID, null, Criteria.EQUAL);
112: moduleCrit.or(crossModule);
113:
114: if (issueType != null) {
115: Criteria.Criterion issueTypeCrit = crit
116: .getNewCriterion(QueryPeer.ISSUE_TYPE_ID,
117: issueType.getIssueTypeId(),
118: Criteria.EQUAL);
119: Criteria.Criterion nullIssueTypeCrit = crit
120: .getNewCriterion(QueryPeer.ISSUE_TYPE_ID,
121: null, Criteria.EQUAL);
122: moduleCrit.and(issueTypeCrit.or(nullIssueTypeCrit));
123: }
124:
125: if (TYPE_PRIVATE.equals(type)) {
126: crit.add(userPrivateQueriesCrits(user, crit,
127: moduleCrit));
128: } else if (TYPE_GLOBAL.equals(type)) {
129: crit.add(allGlobalQueriesCrit(crit, moduleCrit));
130: } else if (TYPE_ALL_USER.equals(type)) {
131: Criteria.Criterion cuGlob = userUnapprovedQueriesCrits(
132: user, crit, moduleCrit);
133: Criteria.Criterion cPriv = userPrivateQueriesCrits(
134: user, crit, moduleCrit);
135: cuGlob.or(cPriv);
136:
137: Integer moduleOwnerId = module.getOwnerId();
138: Integer userId = user.getUserId();
139: if (moduleOwnerId.equals(userId)) {
140: Criteria.Criterion owner = ownerQueriesCrit(
141: moduleOwnerId, crit, moduleCrit);
142: cuGlob.or(owner);
143: }
144: crit.add(cuGlob);
145: } else {
146: // All queries
147: Criteria.Criterion cGlob = allGlobalQueriesCrit(
148: crit, moduleCrit);
149: Criteria.Criterion cPriv = userPrivateQueriesCrits(
150: user, crit, moduleCrit);
151: cGlob.or(cPriv);
152: crit.add(cGlob);
153: }
154:
155: // Add sort criteria
156: if (SORT_DESCRIPTION.equals(sortColumn)) {
157: addSortOrder(crit, QueryPeer.DESCRIPTION,
158: sortPolarity);
159: } else if (SORT_AVAILABILITY.equals(sortColumn)) {
160: crit
161: .addJoin(QueryPeer.SCOPE_ID,
162: ScopePeer.SCOPE_ID);
163: addSortOrder(crit, ScopePeer.SCOPE_NAME,
164: sortPolarity);
165: } else if (SORT_USER.equals(sortColumn)) {
166: addSortOrder(crit, QueryPeer.USER_ID, sortPolarity);
167: } else {
168: // sort by name
169: addSortOrder(crit, QueryPeer.NAME, sortPolarity);
170: }
171: String tmp = crit.toString();
172: queries = QueryPeer.doSelect(crit);
173: QueryManager.getMethodResult().put(queries, key);
174: } else {
175: queries = (List) obj;
176: }
177: }
178: return queries;
179: }
180:
181: /**
182: * Return all user private queries.
183: * @param user
184: * @param crit
185: * @param moduleCrit
186: * @return
187: */
188: private static Criteria.Criterion userPrivateQueriesCrits(
189: ScarabUser user, Criteria crit,
190: Criteria.Criterion moduleCrit) {
191: Criteria.Criterion cPriv = crit.getNewCriterion(
192: QueryPeer.USER_ID, user.getUserId(), Criteria.EQUAL);
193: cPriv.and(crit.getNewCriterion(QueryPeer.SCOPE_ID,
194: Scope.PERSONAL__PK, Criteria.EQUAL));
195: // need to be careful here, we are adding moduleCrit to
196: // two different criterion. if we switched the order of
197: // the OR below we would screw up cGlob.
198:
199: // [HD] I think the following lines do not make sense,
200: // because as fas as i can see, every Query has a
201: // LIST_ID attached to it. Hence the OR below is
202: // always true and we get all user queries of the
203: // current user here.
204:
205: //Criteria.Criterion notNullListCrit = crit.getNewCriterion(
206: // QueryPeer.LIST_ID, null, Criteria.NOT_EQUAL);
207: //cPriv.and(notNullListCrit.or(moduleCrit));
208:
209: cPriv.and(moduleCrit);
210: return cPriv;
211: }
212:
213: /**
214: * Return the user's private queries AND all queries, which
215: * have scope "module", but have not yet been approved by the
216: * module owner (thus they are still in scope private).
217: * @param user
218: * @param crit
219: * @param moduleCrit
220: * @return
221: */
222: private static Criteria.Criterion userUnapprovedQueriesCrits(
223: ScarabUser user, Criteria crit,
224: Criteria.Criterion moduleCrit) {
225: Criteria.Criterion cUserPendingCrit = crit.getNewCriterion(
226: QueryPeer.USER_ID, user.getUserId(), Criteria.EQUAL);
227: cUserPendingCrit.and(crit.getNewCriterion(QueryPeer.SCOPE_ID,
228: Scope.MODULE__PK, Criteria.EQUAL));
229: cUserPendingCrit.and(crit.getNewCriterion(QueryPeer.APPROVED,
230: Boolean.FALSE, Criteria.EQUAL));
231:
232: // need to be careful here, we are adding moduleCrit to
233: // two different criterion. if we switched the order of
234: // the OR below we would screw up cGlob.
235:
236: // [HD] I think the following lines do not make sense,
237: // because as fas as i can see, every Query has a
238: // LIST_ID attached to it. Hence the OR below is
239: // always true and we get all user queries of the
240: // current user here.
241:
242: //Criteria.Criterion notNullListCrit = crit.getNewCriterion(
243: // QueryPeer.LIST_ID, null, Criteria.NOT_EQUAL);
244: //cUserPendingCrit.and(notNullListCrit.or(moduleCrit));
245:
246: cUserPendingCrit.and(moduleCrit);
247:
248: return cUserPendingCrit;
249: }
250:
251: /**
252: * Return all queries, whith scope "module"
253: * @param crit
254: * @param moduleCrit
255: * @return
256: */
257: private static Criteria.Criterion allGlobalQueriesCrit(
258: Criteria crit, Criteria.Criterion moduleCrit) {
259: Criteria.Criterion cGlob = crit.getNewCriterion(
260: QueryPeer.SCOPE_ID, Scope.MODULE__PK, Criteria.EQUAL);
261:
262: cGlob.and(crit.getNewCriterion(QueryPeer.APPROVED,
263: Boolean.TRUE, Criteria.EQUAL));
264: cGlob.and(moduleCrit);
265: return cGlob;
266: }
267:
268: /**
269: * Return all queries, whith scope "module"
270: * @param crit
271: * @param moduleCrit
272: * @return
273: */
274: private static Criteria.Criterion ownerQueriesCrit(
275: Integer moduleId, Criteria crit,
276: Criteria.Criterion moduleCrit) {
277: Criteria.Criterion cGlob = crit.getNewCriterion(
278: QueryPeer.SCOPE_ID, Scope.MODULE__PK, Criteria.EQUAL);
279:
280: cGlob.and(crit.getNewCriterion(QueryPeer.APPROVED,
281: Boolean.TRUE, Criteria.EQUAL));
282:
283: cGlob.and(crit.getNewCriterion(QueryPeer.MODULE_ID, moduleId,
284: Criteria.EQUAL));
285: cGlob.and(moduleCrit);
286: return cGlob;
287: }
288:
289: public static List getUserQueries(ScarabUser user)
290: throws TorqueException {
291: List queries = null;
292: Object obj = QueryManager.getMethodResult().get(QUERY_PEER,
293: GET_USER_QUERIES, user);
294: if (obj == null) {
295: Criteria crit = new Criteria().add(QueryPeer.DELETED, 0);
296: crit.add(QueryPeer.USER_ID, user.getUserId());
297: queries = QueryPeer.doSelect(crit);
298: QueryManager.getMethodResult().put(queries, QUERY_PEER,
299: GET_USER_QUERIES, user);
300: } else {
301: queries = (List) obj;
302: }
303: return queries;
304: }
305:
306: public static List getModuleQueries(Module module)
307: throws TorqueException {
308: List queries = null;
309: Object obj = QueryManager.getMethodResult().get(QUERY_PEER,
310: GET_MODULE_QUERIES, module);
311: if (obj == null) {
312: Criteria crit = new Criteria().add(QueryPeer.DELETED, 0);
313: crit.add(QueryPeer.MODULE_ID, module.getModuleId());
314: crit.add(QueryPeer.SCOPE_ID, Scope.MODULE__PK);
315: queries = QueryPeer.doSelect(crit);
316: QueryManager.getMethodResult().put(queries, QUERY_PEER,
317: GET_MODULE_QUERIES, module);
318: } else {
319: queries = (List) obj;
320: }
321: return queries;
322: }
323:
324: public static List getQueries(Module module, IssueType issueType,
325: ScarabUser user) throws TorqueException {
326: return getQueries(module, issueType, user, SORT_AVAILABILITY,
327: "asc", TYPE_ALL);
328: }
329:
330: public static List getQueries(Module module, IssueType issueType,
331: ScarabUser user, String sortColumn, String sortPolarity)
332: throws TorqueException {
333: return getQueries(module, issueType, user, sortColumn,
334: sortPolarity, TYPE_ALL);
335: }
336:
337: private static Criteria addSortOrder(Criteria crit,
338: String sortColumn, String sortPolarity) {
339: if (sortPolarity.equals("desc")) {
340: crit.addDescendingOrderByColumn(sortColumn);
341: } else {
342: crit.addAscendingOrderByColumn(sortColumn);
343: }
344: return crit;
345: }
346:
347: }
|