KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > tigris > scarab > om > AbstractScarabUser


1 package org.tigris.scarab.om;
2
3 /* ================================================================
4  * Copyright (c) 2000-2003 CollabNet. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in the
15  * documentation and/or other materials provided with the distribution.
16  *
17  * 3. The end-user documentation included with the redistribution, if
18  * any, must include the following acknowlegement: "This product includes
19  * software developed by CollabNet <http://www.collab.net/>."
20  * Alternately, this acknowlegement may appear in the software itself, if
21  * and wherever such third-party acknowlegements normally appear.
22  *
23  * 4. The hosted project names must not be used to endorse or promote
24  * products derived from this software without prior written
25  * permission. For written permission, please contact info@collab.net.
26  *
27  * 5. Products derived from this software may not use the "Tigris" or
28  * "Scarab" names nor may "Tigris" or "Scarab" appear in their names without
29  * prior written permission of CollabNet.
30  *
31  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
32  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
33  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
34  * IN NO EVENT SHALL COLLAB.NET OR ITS CONTRIBUTORS BE LIABLE FOR ANY
35  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
37  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
38  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
39  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
40  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42  *
43  * ====================================================================
44  *
45  * This software consists of voluntary contributions made by many
46  * individuals on behalf of CollabNet.
47  */

48
49 import java.util.Collections JavaDoc;
50 import java.util.ArrayList JavaDoc;
51 import java.util.Iterator JavaDoc;
52 import java.util.List JavaDoc;
53 import java.util.Locale JavaDoc;
54 import java.util.Map JavaDoc;
55 import java.util.HashMap JavaDoc;
56 import java.util.Comparator JavaDoc;
57 import java.sql.Connection JavaDoc;
58
59 import org.apache.torque.TorqueException;
60 import org.apache.torque.util.Criteria;
61 import org.apache.torque.om.BaseObject;
62
63 import org.apache.fulcrum.localization.Localization;
64
65 import org.tigris.scarab.reports.ReportBridge;
66 import org.tigris.scarab.tools.localization.L10NKeySet;
67 import org.tigris.scarab.util.ScarabException;
68 import org.tigris.scarab.services.security.ScarabSecurity;
69 import org.tigris.scarab.services.cache.ScarabCache;
70 import org.tigris.scarab.util.Log;
71 import org.tigris.scarab.util.ScarabConstants;
72
73 /**
74  * This class contains common code for the use in ScarabUser implementations.
75  * Functionality that is not implementation specific should go here.
76  *
77  * @author <a HREF="mailto:jon@collab.net">Jon S. Stevens</a>
78  * @author <a HREF="mailto:jmcnally@collab.net">John McNally</a>
79  * @version $Id: AbstractScarabUser.java 9104 2004-05-10 21:04:51Z dabbous $
80  */

81 public abstract class AbstractScarabUser
82     extends BaseObject
83 {
84     /** Method name used as part of a cache key */
85     private static final String JavaDoc GET_R_MODULE_USERATTRIBUTES =
86         "getRModuleUserAttributes";
87     /** Method name used as part of a cache key */
88     private static final String JavaDoc GET_R_MODULE_USERATTRIBUTE =
89         "getRModuleUserAttribute";
90
91     private static final String JavaDoc[] HOME_PAGES = {"home,EnterNew.vm",
92         "query", "Index.vm"};
93
94     private static final int MAX_INDEPENDENT_WINDOWS = 10;
95
96     /**
97      * The user's preferred locale.
98      */

99     protected Locale JavaDoc locale = null;
100
101     /**
102      * counter used as part of a key to store an Issue the user is
103      * currently entering
104      */

105     private int issueCount = 0;
106
107     /**
108      * Map to store <code>Issue</code>'s the user is currently entering
109      */

110     private Map JavaDoc issueMap;
111
112     /**
113      * counter used as part of a key to store an ReportBridge the user is
114      * currently editing
115      */

116     private int reportCount = 0;
117
118     /**
119      * Map to store <code>ReportBridge</code>'s the user is currently entering
120      */

121     private Map JavaDoc reportMap;
122
123     /**
124      * Map to store the most recent query entered by the user
125      */

126     private Map JavaDoc mostRecentQueryMap;
127
128     /**
129      * Map to store the MITList that may have went with the most recent query
130      * entered by the user
131      */

132     private Map JavaDoc mostRecentQueryMITMap;
133
134     /**
135      * Map to store the working user list in Assign Issue.
136      */

137     private Map JavaDoc associatedUsersMap;
138
139     /**
140      * Map to store the working user list in Advanced Query.
141      */

142     private Map JavaDoc selectedUsersMap;
143
144     /**
145      * Code for user's preference on which screen to return to
146      * After entering an issue
147      */

148     private int enterIssueRedirect = 0;
149
150     /**
151      * The list of MITListItems that will be searched in a
152      * X-project query.
153      */

154     private Map JavaDoc mitListMap;
155
156     /**
157      * The last entered issue type
158      */

159     private Map JavaDoc enterIssueMap;
160
161     /**
162      * toggle switch for show/hide the cross module section of the
163      * issue type selection widget.
164      */

165     private boolean showOtherModulesInIssueTypeList;
166
167     private Map JavaDoc activeKeys = new HashMap JavaDoc();
168     private transient ThreadLocal JavaDoc threadKey = null;
169
170     /**
171      * counter used as a key to keep concurrent activities by the same
172      * user from overwriting each others state. Might want to use something
173      * better than a simple counter.
174      */

175     private int threadCount = 0;
176
177     // we could create Maps for these and use the threadKey, but these
178
// will be reset for each request, so we can keep it simple and use
179
// a ThreadLocal for each. Even though the threads may be pooled the
180
// value will be set correctly when first needed in a request cycle.
181
private transient ThreadLocal JavaDoc currentModule = null;
182     private transient ThreadLocal JavaDoc currentIssueType = null;
183
184     /**
185      * Calls the superclass constructor to initialize this object.
186      */

187     public AbstractScarabUser()
188     {
189         super();
190         issueMap = new HashMap JavaDoc();
191         reportMap = new HashMap JavaDoc();
192         mitListMap = new HashMap JavaDoc();
193         enterIssueMap = new HashMap JavaDoc();
194         mostRecentQueryMap = new HashMap JavaDoc();
195         mostRecentQueryMITMap = new HashMap JavaDoc();
196         associatedUsersMap = new HashMap JavaDoc();
197         selectedUsersMap = new HashMap JavaDoc();
198         initThreadLocals();
199     }
200
201     /**
202      * Need to override readObject in order to initialize
203      * the transient ThreadLocal objects which are not serializable.
204      */

205     private void readObject(java.io.ObjectInputStream JavaDoc in)
206          throws java.io.IOException JavaDoc, ClassNotFoundException JavaDoc
207     {
208         try
209         {
210             in.defaultReadObject();
211         }
212         catch (java.io.NotActiveException JavaDoc e)
213         {
214         }
215         initThreadLocals();
216     }
217
218     private void initThreadLocals()
219     {
220         currentIssueType = new ThreadLocal JavaDoc();
221         currentModule = new ThreadLocal JavaDoc();
222         threadKey = new ThreadLocal JavaDoc();
223     }
224
225     /** The Primary Key used to reference this user in storage */
226     public abstract Integer JavaDoc getUserId();
227
228     /**
229      * @see org.tigris.scarab.om.ScarabUser#getEmail()
230      */

231     public abstract String JavaDoc getEmail();
232
233     /**
234      * @see org.tigris.scarab.om.ScarabUser#getFirstName()
235      */

236     public abstract String JavaDoc getFirstName();
237
238     /**
239      * @see org.tigris.scarab.om.ScarabUser#getLastName()
240      */

241     public abstract String JavaDoc getLastName();
242
243     /**
244      * @see org.tigris.scarab.om.ScarabUser#hasPermission(String, Module)
245      */

246     public abstract boolean hasPermission(String JavaDoc perm, Module module);
247
248     /**
249      * @see org.tigris.scarab.om.ScarabUser#hasPermission(String, List)
250      */

251     public boolean hasPermission(String JavaDoc perm, List JavaDoc modules)
252     {
253         boolean hasPerm = false;
254         if (modules != null && !modules.isEmpty())
255         {
256             hasPerm = true;
257             Iterator JavaDoc i = modules.iterator();
258             while (i.hasNext() && hasPerm)
259             {
260                 hasPerm = hasPermission(perm, (Module)i.next());
261             }
262         }
263         return hasPerm;
264     }
265
266     /**
267      * @see org.tigris.scarab.om.ScarabUser#getName()
268      * It will be the "FirstName LastName", if both names have a value.
269      */

270     public String JavaDoc getName()
271     {
272         String JavaDoc first = getFirstName();
273         String JavaDoc last = getLastName();
274         int firstlength = 0;
275         int lastlength = 0;
276         if (first != null)
277         {
278             firstlength = first.length();
279         }
280         if (last != null)
281         {
282             lastlength = last.length();
283         }
284         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(firstlength + lastlength + 1);
285         if (firstlength > 0)
286         {
287             sb.append(first);
288             if (lastlength > 0)
289             {
290                 sb.append(' ');
291             }
292         }
293         if (lastlength > 0)
294         {
295             sb.append(last);
296         }
297         
298         return sb.toString();
299     }
300
301     /**
302      * @see org.tigris.scarab.om.ScarabUser#getModules()
303      */

304     public abstract List JavaDoc getModules() throws Exception JavaDoc;
305
306     /**
307      * @see org.tigris.scarab.om.ScarabUser#getModules(String)
308      */

309     public abstract Module[] getModules(String JavaDoc permission) throws Exception JavaDoc;
310
311     /**
312      * @see org.tigris.scarab.om.ScarabUser#getModules(boolean)
313      */

314     public abstract List JavaDoc getModules(boolean showDeletedModules)
315         throws Exception JavaDoc;
316
317     /**
318      * @see org.tigris.scarab.om.ScarabUser#getEditableModules()
319      */

320     public List JavaDoc getEditableModules()
321         throws Exception JavaDoc
322     {
323         return getEditableModules(null);
324     }
325
326
327     /**
328      * Get modules user can copy or move to.
329      * If copying, requires ISSUE_ENTER permission
330      * If moving, requires ISSUE_MOVE permission to move
331      * To another module, or ISSUE_EDIT to move to another issue type.
332      */

333     public List JavaDoc getCopyToModules(Module currentModule, String JavaDoc action,
334                                  String JavaDoc searchString)
335         throws Exception JavaDoc
336     {
337         List JavaDoc copyToModules = new ArrayList JavaDoc();
338         if (hasPermission(ScarabSecurity.ISSUE__MOVE, currentModule)
339             || "copy".equals(action))
340         {
341             Module[] userModules = getModules(ScarabSecurity.ISSUE__ENTER);
342             for (int i=0; i<userModules.length; i++)
343             {
344                 Module module = userModules[i];
345                 if (!module.isGlobalModule() &&
346                     (searchString == null || searchString.equals("") ||
347                      module.getName().indexOf(searchString) != -1))
348                 {
349                     copyToModules.add(module);
350                 }
351             }
352         }
353         else if (hasPermission(ScarabSecurity.ISSUE__EDIT, currentModule)
354                  && currentModule.getIssueTypes().size() > 1)
355         {
356             copyToModules.add(currentModule);
357         }
358         return copyToModules;
359     }
360
361     /**
362      * @see org.tigris.scarab.om.ScarabUser#getCopyToModules(Module)
363      */

364     public List JavaDoc getCopyToModules(Module currentModule)
365         throws Exception JavaDoc
366     {
367         return getCopyToModules(currentModule, "copy", null);
368     }
369
370     /**
371      * @see org.tigris.scarab.om.ScarabUser#getCopyToModules(Module, String)
372      */

373     public List JavaDoc getCopyToModules(Module currentModule, String JavaDoc action)
374         throws Exception JavaDoc
375     {
376         return getCopyToModules(currentModule, action, null);
377     }
378
379     /**
380      * @see org.tigris.scarab.om.ScarabUser#getEditableModules(Module)
381      */

382     public List JavaDoc getEditableModules(Module currEditModule)
383         throws Exception JavaDoc
384     {
385         List JavaDoc userModules = getModules(true);
386         List JavaDoc editModules = new ArrayList JavaDoc();
387
388         if (currEditModule != null)
389         {
390             editModules.add(currEditModule.getParent());
391         }
392         for (int i=0; i<userModules.size(); i++)
393         {
394             Module module = (Module)userModules.get(i);
395             Module parent = module.getParent();
396
397             if (!editModules.contains(module) && parent != currEditModule)
398             {
399                 if (hasPermission(ScarabSecurity.MODULE__EDIT, module))
400                 {
401                     editModules.add(module);
402                 }
403             }
404         }
405         // we want to remove the module we are editing
406
if (currEditModule != null && editModules.contains(currEditModule))
407         {
408             editModules.remove(currEditModule);
409         }
410
411         return editModules;
412     }
413
414     /**
415      * @see org.tigris.scarab.om.ScarabUser#getRModuleUserAttributes(Module, IssueType)
416      */

417     public List JavaDoc getRModuleUserAttributes(Module module,
418                                          IssueType issueType)
419         throws Exception JavaDoc
420     {
421         List JavaDoc result = null;
422         Object JavaDoc obj = ScarabCache.get(this, GET_R_MODULE_USERATTRIBUTES,
423                                      module, issueType);
424         if (obj == null)
425         {
426             Criteria crit = new Criteria()
427                 .add(RModuleUserAttributePeer.USER_ID, getUserId())
428                 .add(RModuleUserAttributePeer.MODULE_ID, module.getModuleId())
429                 .add(RModuleUserAttributePeer.ISSUE_TYPE_ID,
430                      issueType.getIssueTypeId())
431                 .addAscendingOrderByColumn(
432                     RModuleUserAttributePeer.PREFERRED_ORDER);
433             
434             result = getRModuleUserAttributes(crit);
435             ScarabCache.put(result, this, GET_R_MODULE_USERATTRIBUTES,
436                             module, issueType);
437         }
438         else
439         {
440             result = (List JavaDoc)obj;
441         }
442         return result;
443     }
444
445     /**
446      * Should return a list of <code>RModuleUserAttribute</code>'s that
447      * meet the given criteria.
448      */

449     protected abstract List JavaDoc getRModuleUserAttributes(Criteria crit)
450         throws TorqueException;
451
452     /**
453      * @see org.tigris.scarab.om.ScarabUser#getRModuleUserAttribute(Module, Attribute, IssueType)
454      */

455     public RModuleUserAttribute getRModuleUserAttribute(Module module,
456                                                        Attribute attribute,
457                                                        IssueType issueType)
458         throws Exception JavaDoc
459     {
460         RModuleUserAttribute result = null;
461         Object JavaDoc obj = ScarabCache.get(this, GET_R_MODULE_USERATTRIBUTE,
462                                      module, attribute, issueType);
463         if (obj == null)
464         {
465             Criteria crit = new Criteria(4)
466                 .add(RModuleUserAttributePeer.USER_ID, getUserId())
467                 .add(RModuleUserAttributePeer.ATTRIBUTE_ID,
468                      attribute.getAttributeId())
469                 .add(RModuleUserAttributePeer.LIST_ID, null);
470             if (module == null)
471             {
472                 crit.add(RModuleUserAttributePeer.MODULE_ID, null);
473             }
474             else
475             {
476                 crit.add(RModuleUserAttributePeer.MODULE_ID,
477                          module.getModuleId());
478                 
479             }
480             if (issueType == null)
481             {
482                 crit.add(RModuleUserAttributePeer.ISSUE_TYPE_ID, null);
483             }
484             else
485             {
486                 crit.add(RModuleUserAttributePeer.ISSUE_TYPE_ID,
487                          issueType.getIssueTypeId());
488             }
489             
490             List JavaDoc muas = RModuleUserAttributePeer.doSelect(crit);
491             if (muas.size() == 1)
492             {
493                 result = (RModuleUserAttribute)muas.get(0);
494             }
495             else if (muas.isEmpty())
496             {
497                 result =
498                     getNewRModuleUserAttribute(attribute, module, issueType);
499             }
500             else
501             {
502                 throw new ScarabException(L10NKeySet.ExceptionMultipleJDMs);
503             }
504             ScarabCache.put(result, this, GET_R_MODULE_USERATTRIBUTE,
505                             module, attribute, issueType);
506         }
507         else
508         {
509             result = (RModuleUserAttribute)obj;
510         }
511         return result;
512     }
513     
514     protected RModuleUserAttribute getNewRModuleUserAttribute(
515         Attribute attribute, Module module, IssueType issueType)
516         throws Exception JavaDoc
517     {
518         RModuleUserAttribute result = RModuleUserAttributeManager.getInstance();
519         result.setUserId(getUserId());
520         result.setAttributeId(attribute.getAttributeId());
521         if (module != null)
522         {
523             result.setModuleId(module.getModuleId());
524         }
525         if (issueType != null)
526         {
527             result.setIssueTypeId(issueType.getIssueTypeId());
528         }
529         return result;
530     }
531
532     /**
533      * @see org.tigris.scarab.om.ScarabUser#getReportingIssue(String)
534      */

535     public Issue getReportingIssue(String JavaDoc key)
536     {
537         return (Issue)issueMap.get(key);
538     }
539
540
541     /**
542      * @see org.tigris.scarab.om.ScarabUser#setReportingIssue(Issue)
543      */

544     public String JavaDoc setReportingIssue(Issue issue)
545         throws ScarabException
546     {
547         String JavaDoc key = null;
548         if (issue == null)
549         {
550             throw new ScarabException(L10NKeySet.ExceptionNullIssueForbidden);
551         }
552         else
553         {
554             key = String.valueOf(issueCount++);
555             setReportingIssue(key, issue);
556         }
557         return key;
558     }
559
560
561     /**
562      * @see org.tigris.scarab.om.ScarabUser#setReportingIssue(String, Issue)
563      */

564     public void setReportingIssue(String JavaDoc key, Issue issue)
565     {
566         if (issue == null)
567         {
568             issueMap.remove(key);
569         }
570         else
571         {
572             try
573             {
574                 if (issueMap.size() >= MAX_INDEPENDENT_WINDOWS)
575                 {
576                     // make sure issues are not being accumulated, set a
577
// reasonable limit of 10 open new issues
578
int intKey = Integer.parseInt(key);
579                     int count = 0;
580                     for (int i=intKey-1; i>=0; i--)
581                     {
582                         String JavaDoc testKey = String.valueOf(i);
583                         if (getReportingIssue(testKey) != null)
584                         {
585                             if (++count >= MAX_INDEPENDENT_WINDOWS)
586                             {
587                                 issueMap.remove(testKey);
588                             }
589                         }
590                     }
591                 }
592             }
593             catch (Exception JavaDoc e)
594             {
595                 Log.get().error("Nonfatal error clearing old issues. "
596                                 + "This could be a memory leak.", e);
597             }
598             
599             issueMap.put(key, issue);
600         }
601     }
602
603
604
605     /**
606      * @see org.tigris.scarab.om.ScarabUser#getCurrentReport(String)
607      */

608     public ReportBridge getCurrentReport(String JavaDoc key)
609     {
610         return (ReportBridge)reportMap.get(key);
611     }
612
613
614     /**
615      * @see org.tigris.scarab.om.ScarabUser#setCurrentReport(ReportBridge)
616      */

617     public String JavaDoc setCurrentReport(ReportBridge report)
618         throws ScarabException
619     {
620         String JavaDoc key = null;
621         if (report == null)
622         {
623             throw new ScarabException(L10NKeySet.ExceptionNullReportForbidden);
624         }
625         else
626         {
627             key = String.valueOf(reportCount++);
628             setCurrentReport(key, report);
629         }
630         return key;
631     }
632
633
634     /**
635      * @see org.tigris.scarab.om.ScarabUser#setCurrentReport(String, ReportBridge)
636      */

637     public void setCurrentReport(String JavaDoc key, ReportBridge report)
638     {
639         if (report == null)
640         {
641             reportMap.remove(key);
642         }
643         else
644         {
645             try
646             {
647                 if (reportMap.size() >= MAX_INDEPENDENT_WINDOWS)
648                 {
649                     // make sure reports are not being accumulated, set a
650
// reasonable limit of MAX_INDEPENDENT_WINDOWS open reports
651
int intKey = Integer.parseInt(key);
652                     int count = 0;
653                     for (int i=intKey-1; i>=0; i--)
654                     {
655                         String JavaDoc testKey = String.valueOf(i);
656                         if (getCurrentReport(testKey) != null)
657                         {
658                             if (++count >= MAX_INDEPENDENT_WINDOWS)
659                             {
660                                 reportMap.remove(testKey);
661                             }
662                         }
663                     }
664                 }
665             }
666             catch (Exception JavaDoc e)
667             {
668                 Log.get().error("Nonfatal error clearing old reports. "
669                                 + "This could be a memory leak.", e);
670             }
671
672             reportMap.put(String.valueOf(key), report);
673         }
674     }
675
676
677     /**
678      * @see org.apache.torque.om.Persistent#save()
679      * this implementation throws an UnsupportedOperationException.
680      */

681     public void save() throws Exception JavaDoc
682     {
683         throw new UnsupportedOperationException JavaDoc("Not implemented"); //EXCEPTION
684
}
685
686     /**
687      * @see org.apache.torque.om.Persistent#save(String)
688      * this implementation throws an UnsupportedOperationException.
689      */

690     public void save(String JavaDoc dbName) throws Exception JavaDoc
691     {
692         throw new UnsupportedOperationException JavaDoc("Not implemented"); //EXCEPTION
693
}
694
695     /**
696      * @see org.apache.torque.om.Persistent#save(Connection)
697      * this implementation throws an UnsupportedOperationException.
698      */

699     public void save(Connection JavaDoc dbCon) throws Exception JavaDoc
700     {
701         throw new UnsupportedOperationException JavaDoc("Not implemented"); //EXCEPTION
702
}
703
704     /**
705      * Returns integer representing user preference for
706      * Which screen to return to after entering an issue.
707      * 1 = Enter New Issue. 2 = Assign Issue (default)
708      * 3 = View Issue. 4 = Issue Types index.
709      */

710     public int getEnterIssueRedirect()
711         throws TorqueException
712     {
713         if (enterIssueRedirect == 0)
714         {
715             UserPreference up = UserPreferenceManager.getInstance(getUserId());
716             if (up != null && up.getEnterIssueRedirect() != 0)
717             {
718                 enterIssueRedirect = up.getEnterIssueRedirect();
719             }
720         }
721         return enterIssueRedirect;
722     }
723     
724
725     /**
726      * Sets integer representing user preference for
727      * Which screen to return to after entering an issue.
728      * 1 = Enter New Issue. 2 = Assign Issue (default)
729      * 3 = View Issue. 4 = Issue Types index.
730      */

731     public void setEnterIssueRedirect(int templateCode)
732         throws Exception JavaDoc
733     {
734         UserPreference up = UserPreferenceManager.getInstance(getUserId());
735         up.setEnterIssueRedirect(templateCode);
736         up.save();
737         enterIssueRedirect = templateCode;
738     }
739
740     /**
741      * @see ScarabUser#getHomePage()
742      */

743     public String JavaDoc getHomePage()
744         throws Exception JavaDoc
745     {
746         return getHomePage(getCurrentModule());
747     }
748
749     /**
750      * @see ScarabUser#getHomePage(Module)
751      */

752     public String JavaDoc getHomePage(Module module)
753     {
754         String JavaDoc homePage = null;
755         try
756         {
757             // A user with no id won't have preferences. The
758
// anonymous user used during password expiration (or an
759
// unsaved user) would exhibit this behavior.
760
Integer JavaDoc uid = getUserId();
761             if (uid != null)
762             {
763                 UserPreference up = UserPreferenceManager.getInstance(uid);
764                 homePage = up.getHomePage();
765
766                 if ("query".equals(homePage))
767                 {
768                     homePage = getQueryTarget();
769                 }
770                 // protect against removal of old screens
771
else if (homePage != null &&
772                     (homePage.endsWith("ModuleQuery.vm") ||
773                      homePage.endsWith("XModuleList.vm")))
774                 {
775                     homePage = getQueryTarget();
776                 }
777
778                 int i = 0;
779                 while (homePage == null || !isHomePageValid(homePage, module))
780                 {
781                     homePage = HOME_PAGES[i++];
782                     if ("query".equals(homePage))
783                     {
784                         homePage = getQueryTarget();
785                     }
786                 }
787             }
788         }
789         catch (Exception JavaDoc e)
790         {
791             Log.get().warn("Error determining user homepage", e);
792         }
793         return (homePage != null ? homePage : "Index.vm");
794     }
795
796     /**
797      * This method is used in getHomePage() and expects the homePage to
798      * be non-null.
799      */

800     private boolean isHomePageValid(String JavaDoc homePage, Module module)
801     {
802         boolean result = true;
803         String JavaDoc perm = ScarabSecurity
804             .getScreenPermission(homePage.replace(',','.'));
805         if (perm != null && !hasPermission(perm, module))
806         {
807             result = false;
808         }
809         return result;
810     }
811
812     /**
813      * @see ScarabUser#setHomePage(String)
814      */

815     public void setHomePage(String JavaDoc homePage)
816         throws Exception JavaDoc
817     {
818         if ("ModuleNotReady.vm".equals(homePage))
819         {
820             throw new ScarabException(L10NKeySet.ExceptionForbiddenHomeModuleNotReady);
821         }
822         UserPreference up = UserPreferenceManager.getInstance(getUserId());
823         up.setHomePage(homePage);
824         up.save();
825     }
826
827     // TODO: make this persist
828
private final Map JavaDoc queryTargetMap = new HashMap JavaDoc();
829     /**
830      * @see ScarabUser#getQueryTarget()
831      */

832     public String JavaDoc getQueryTarget()
833     {
834         MITList mitlist = getCurrentMITList();
835         String JavaDoc target = null;
836         if (mitlist == null)
837         {
838             target = "IssueTypeList.vm";
839         }
840         else if (mitlist.isSingleModuleIssueType())
841         {
842             try
843             {
844                 Integer JavaDoc issueTypeId = mitlist.getIssueType().getIssueTypeId();
845                 target = (String JavaDoc)queryTargetMap.get(issueTypeId);
846             }
847             catch (Exception JavaDoc e)
848             {
849                 Log.get().warn("Could not determine query target.", e);
850             }
851             
852             if (target == null)
853             {
854                 target = "Search.vm";
855             }
856         }
857         else
858         {
859             target = "AdvancedQuery.vm";
860         }
861         return target;
862     }
863
864     /**
865      * @see ScarabUser#setSingleIssueTypeQueryTarget(IssueType, String)
866      */

867     public void setSingleIssueTypeQueryTarget(IssueType type, String JavaDoc target)
868     {
869         queryTargetMap.put(type.getIssueTypeId(), target);
870     }
871
872     /**
873      * Gets active, named lists
874      *
875      * @return a <code>List</code> value
876      * @exception TorqueException if an error occurs
877      */

878     public List JavaDoc getMITLists()
879         throws TorqueException
880     {
881         List JavaDoc result = null;
882
883         Criteria crit = new Criteria();
884         crit.add(MITListPeer.ACTIVE, true);
885         Criteria.Criterion userCrit = crit.getNewCriterion(
886             MITListPeer.USER_ID, getUserId(), Criteria.EQUAL);
887         userCrit.or(crit.getNewCriterion(
888             MITListPeer.USER_ID, null, Criteria.EQUAL));
889         crit.add(userCrit);
890         crit.add(MITListPeer.MODIFIABLE, true);
891         crit.add(MITListPeer.ACTIVE, true);
892         crit.add(MITListPeer.NAME, (Object JavaDoc)null, Criteria.NOT_EQUAL);
893         crit.addAscendingOrderByColumn(MITListPeer.NAME);
894         result = MITListPeer.doSelect(crit);
895
896         return result;
897     }
898
899
900     /**
901      * @see ScarabUser#hasAnySearchableRMITs().
902      */

903     public boolean hasAnySearchableRMITs()
904         throws Exception JavaDoc
905     {
906         boolean result = false;
907         List JavaDoc moduleIds = getSearchableModuleIds();
908         if (!moduleIds.isEmpty())
909         {
910             Criteria crit = new Criteria();
911             crit.addIn(RModuleIssueTypePeer.MODULE_ID, moduleIds);
912             result = (RModuleIssueTypePeer.count(crit) > 0);
913         }
914         return result;
915     }
916
917     private List JavaDoc getSearchableModuleIds()
918         throws Exception JavaDoc
919     {
920         Module[] userModules = getModules(ScarabSecurity.ISSUE__SEARCH);
921         List JavaDoc moduleIds;
922         if (userModules != null && (userModules.length > 1 ||
923                 userModules.length == 1 && !userModules[0].isGlobalModule())
924            )
925         {
926             moduleIds = new ArrayList JavaDoc(userModules.length);
927             for (int i=0; i<userModules.length; i++)
928             {
929                 Module module = userModules[i];
930                 if (!module.isGlobalModule())
931                 {
932                     moduleIds.add(module.getModuleId());
933                 }
934             }
935         }
936         else
937         {
938             moduleIds = Collections.EMPTY_LIST;
939         }
940         return moduleIds;
941     }
942
943
944     /**
945      * @see ScarabUser#getUnusedRModuleIssueTypes(Module).
946      */

947     public List JavaDoc getUnusedRModuleIssueTypes(Module module)
948         throws Exception JavaDoc
949     {
950         Criteria crit = new Criteria();
951         crit.add(RModuleIssueTypePeer.MODULE_ID, module.getModuleId())
952             .addJoin(RModuleIssueTypePeer.ISSUE_TYPE_ID,
953                      IssueTypePeer.ISSUE_TYPE_ID)
954             .add(IssueTypePeer.PARENT_ID, 0)
955             .add(IssueTypePeer.DELETED, false);
956         addCurrentMITListExclusion(crit);
957         return RModuleIssueTypePeer.doSelect(crit);
958     }
959
960     private void addCurrentMITListExclusion(Criteria crit)
961         throws Exception JavaDoc
962     {
963             // do not include RMIT's related to current MITListItems.
964
MITList mitList = getCurrentMITList(getGenThreadKey());
965             if (mitList != null && mitList.getMITListItems() != null
966                 && !mitList.getMITListItems().isEmpty())
967             {
968                 boolean addAnd = false;
969                 StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
970                 Iterator JavaDoc mitItems =
971                     mitList.getExpandedMITListItems().iterator();
972                 while (mitItems.hasNext())
973                 {
974                     MITListItem item = (MITListItem)mitItems.next();
975                     if (mitList.getModule(item) != null
976                         && item.getIssueType() != null)
977                     {
978                         if (addAnd)
979                         {
980                             sb.append(" AND ");
981                         }
982                         
983                         sb.append(" NOT (")
984                             .append(RModuleIssueTypePeer.MODULE_ID)
985                             .append('=')
986                             .append(mitList.getModule(item).getModuleId())
987                             .append(" AND ")
988                             .append(RModuleIssueTypePeer.ISSUE_TYPE_ID)
989                             .append('=')
990                             .append(item.getIssueType().getIssueTypeId())
991                             .append(')');
992                         addAnd = true;
993                     }
994                 }
995                 // the column name used here is arbitrary (within limits)
996
crit.add(IssueTypePeer.ISSUE_TYPE_ID,
997                          (Object JavaDoc)sb.toString(), Criteria.CUSTOM);
998             }
999     }
1000
1001    /**
1002     * @see ScarabUser#getSearchableRMITs(String, String, String, String, Module).
1003     * This list does not include
1004     * RModuleIssueTypes that are part of the current MITList.
1005     */

1006    public List JavaDoc getSearchableRMITs(String JavaDoc searchField, String JavaDoc searchString,
1007                                   String JavaDoc sortColumn, String JavaDoc sortPolarity,
1008                                   Module skipModule)
1009        throws Exception JavaDoc
1010    {
1011        List JavaDoc moduleIds = getSearchableModuleIds();
1012        if (skipModule != null)
1013        {
1014            moduleIds.remove(skipModule.getModuleId());
1015        }
1016        
1017        List JavaDoc result;
1018        if (moduleIds.isEmpty())
1019        {
1020            result = Collections.EMPTY_LIST;
1021        }
1022        else
1023        {
1024            Criteria crit = new Criteria();
1025            crit.addIn(RModuleIssueTypePeer.MODULE_ID, moduleIds);
1026            crit.addJoin(RModuleIssueTypePeer.ISSUE_TYPE_ID,
1027                         IssueTypePeer.ISSUE_TYPE_ID);
1028            crit.add(IssueTypePeer.PARENT_ID, 0);
1029            crit.add(IssueTypePeer.DELETED, false);
1030            addCurrentMITListExclusion(crit);
1031
1032            // we could add the filter criteria here, but this might
1033
// result in full table scans. Even if the table scan turns out
1034
// to be more efficient, I think it is better to move this
1035
// into the middle/front tier.
1036
//addFilterCriteria(crit, searchField, searchString);
1037
//addSortCriteria(crit, sortColumn, sortPolarity);
1038

1039            result = RModuleIssueTypePeer.doSelect(crit);
1040            filterRMITList(result, searchField, searchString);
1041            sortRMITList(result, sortColumn, sortPolarity);
1042        }
1043        
1044        return result;
1045    }
1046
1047    /**
1048     * Filter on module or issue type name.
1049     */

1050    protected void filterRMITList(List JavaDoc rmits,
1051                                  String JavaDoc searchField, String JavaDoc searchString)
1052        throws Exception JavaDoc
1053    {
1054        String JavaDoc moduleName = null;
1055        String JavaDoc issueTypeName = null;
1056        if ("issuetype".equals(searchField))
1057        {
1058            issueTypeName = searchString;
1059        }
1060        else
1061        {
1062            moduleName = searchString;
1063        }
1064        
1065        if (moduleName != null && moduleName.length() > 0)
1066        {
1067            for (int i=rmits.size()-1; i>=0; i--)
1068            {
1069                String JavaDoc name = ((RModuleIssueType)rmits.get(i))
1070                    .getModule().getRealName();
1071                if (name == null || name.indexOf(moduleName) == -1)
1072                {
1073                    rmits.remove(i);
1074                }
1075            }
1076        }
1077        if (issueTypeName != null && issueTypeName.length() > 0)
1078        {
1079            for (int i=rmits.size()-1; i>=0; i--)
1080            {
1081                String JavaDoc name = ((RModuleIssueType)rmits.get(i))
1082                    .getDisplayName();
1083                if (name == null || name.indexOf(issueTypeName) == -1)
1084                {
1085                    rmits.remove(i);
1086                }
1087            }
1088        }
1089    }
1090
1091    /**
1092     * Sort module or issue type name.
1093     */

1094    protected void sortRMITList(List JavaDoc rmits,
1095                                final String JavaDoc sortColumn, String JavaDoc sortPolarity)
1096        throws Exception JavaDoc
1097    {
1098        final int polarity = ("desc".equals(sortPolarity)) ? -1 : 1;
1099        Comparator JavaDoc c = new Comparator JavaDoc()
1100        {
1101            public int compare(Object JavaDoc o1, Object JavaDoc o2)
1102            {
1103                int i = 0;
1104                if (sortColumn != null && sortColumn.equals("issuetype"))
1105                {
1106                    i = polarity * ((RModuleIssueType)o1).getDisplayName()
1107                         .compareTo(((RModuleIssueType)o2).getDisplayName());
1108                }
1109                else
1110                {
1111                    try
1112                    {
1113                        i = polarity *
1114                            ((RModuleIssueType)o1).getModule().getRealName()
1115                            .compareTo(((RModuleIssueType)o2).getModule()
1116                                       .getRealName());
1117                    }
1118                    catch (TorqueException e)
1119                    {
1120                        Log.get().error("Unable to sort on module names", e);
1121                    }
1122                }
1123                return i;
1124             }
1125        };
1126        Collections.sort(rmits, c);
1127    }
1128
1129
1130    public void addRMITsToCurrentMITList(List JavaDoc rmits)
1131        throws TorqueException
1132    {
1133        if (rmits != null && !rmits.isEmpty())
1134        {
1135            MITList mitList = getCurrentMITList(getGenThreadKey());
1136            if (mitList == null)
1137            {
1138                mitList = MITListManager.getInstance();
1139                setCurrentMITList(mitList);
1140            }
1141
1142            Iterator JavaDoc i = rmits.iterator();
1143            while (i.hasNext())
1144            {
1145                RModuleIssueType rmit = (RModuleIssueType)i.next();
1146                MITListItem item = MITListItemManager.getInstance();
1147                item.setModuleId(rmit.getModuleId());
1148                item.setIssueTypeId(rmit.getIssueTypeId());
1149                if (!mitList.contains(item))
1150                {
1151                    mitList.addMITListItem(item);
1152                }
1153            }
1154        }
1155    }
1156
1157    private Object JavaDoc getGenThreadKey()
1158    {
1159        Object JavaDoc key = threadKey.get();
1160        if (key == null)
1161        {
1162            key = getNewThreadKey();
1163            setThreadKey((Integer JavaDoc)key);
1164        }
1165        return key;
1166    }
1167
1168    private synchronized Object JavaDoc getNewThreadKey()
1169    {
1170        // this algorithm is not very good. what happens if someone bookmarks
1171
// a deep link which includes a thread key
1172
Integer JavaDoc key = new Integer JavaDoc(threadCount++);
1173        activeKeys.put(key, null);
1174        // make sure user is not using up too many resources, set a
1175
// reasonable limit of 10 open "threads"/browser windows.
1176
Integer JavaDoc testKey = new Integer JavaDoc(key.intValue()-10);
1177        invalidateKey(testKey);
1178        return key;
1179    }
1180
1181    private void invalidateKey(Object JavaDoc key)
1182    {
1183        activeKeys.remove(key);
1184        mitListMap.remove(key);
1185        enterIssueMap.remove(key);
1186    }
1187
1188    /**
1189     * @see ScarabUser#getThreadKey()
1190     */

1191    public Object JavaDoc getThreadKey()
1192    {
1193        return threadKey.get();
1194    }
1195
1196    /**
1197     * @see ScarabUser#setThreadKey(Integer)
1198     */

1199    public void setThreadKey(Integer JavaDoc key)
1200    {
1201        if (activeKeys.containsKey(key))
1202        {
1203            threadKey.set(key);
1204        }
1205    }
1206
1207    public MITList getCurrentMITList()
1208    {
1209        return getCurrentMITList(getGenThreadKey());
1210    }
1211    private MITList getCurrentMITList(Object JavaDoc key)
1212    {
1213        Log.get().debug("Getting mitlist for key " + key);
1214        return (MITList)mitListMap.get(key);
1215    }
1216
1217    /**
1218     * @see org.tigris.scarab.om.ScarabUser#setCurrentMITList(MITList)
1219     */

1220    public void setCurrentMITList(MITList list)
1221    {
1222        if (list != null)
1223        {
1224            setCurrentMITList(getGenThreadKey(), list);
1225        }
1226        else if (getThreadKey() != null)
1227        {
1228            setCurrentMITList(getThreadKey(), list);
1229        }
1230    }
1231    private void setCurrentMITList(Object JavaDoc key, MITList list)
1232    {
1233        if (list == null)
1234        {
1235            mitListMap.remove(key);
1236        }
1237        else
1238        {
1239            try
1240            {
1241                if (mitListMap.size() >= MAX_INDEPENDENT_WINDOWS)
1242                {
1243                    // make sure lists are not being accumulated, set a
1244
// reasonable limit of MAX_INDEPENDENT_WINDOWS open lists
1245
int intKey = Integer.parseInt(String.valueOf(key));
1246                    int count = 0;
1247                    for (int i=intKey-1; i>=0; i--)
1248                    {
1249                        String JavaDoc testKey = String.valueOf(i);
1250                        if (getCurrentMITList(testKey) != null)
1251                        {
1252                            if (++count >= MAX_INDEPENDENT_WINDOWS)
1253                            {
1254                                mitListMap.remove(testKey);
1255                            }
1256                        }
1257                    }
1258                }
1259            }
1260            catch (Exception JavaDoc e)
1261            {
1262                Log.get().error("Nonfatal error clearing old MIT lists. "
1263                                + "This could be a memory leak.", e);
1264            }
1265            Log.get().debug("Set mitList for key " + key + " to " + list);
1266            
1267            mitListMap.put(key, list);
1268        }
1269    }
1270
1271    public void removeItemsFromCurrentMITList(String JavaDoc[] ids)
1272    {
1273        MITList mitList = getCurrentMITList(getGenThreadKey());
1274        if (mitList != null && !mitList.isEmpty()
1275            && ids != null && ids.length > 0)
1276        {
1277            for (int i=0; i<ids.length; i++)
1278            {
1279                Iterator JavaDoc iter = mitList.iterator();
1280                while (iter.hasNext())
1281                {
1282                    MITListItem item = (MITListItem)iter.next();
1283                    if (item.getQueryKey().equals(ids[i]))
1284                    {
1285                        iter.remove();
1286                        mitList.scheduleItemForDeletion(item);
1287                        continue;
1288                    }
1289                }
1290                
1291            }
1292        }
1293    }
1294
1295    /**
1296     * @see org.tigris.scarab.om.ScarabUser#hasMostRecentQuery()
1297     */

1298    public boolean hasMostRecentQuery()
1299    {
1300        return hasMostRecentQuery(getGenThreadKey());
1301    }
1302    private boolean hasMostRecentQuery(Object JavaDoc key)
1303    {
1304        return mostRecentQueryMap.get(key) != null;
1305    }
1306
1307    /**
1308     * @see org.tigris.scarab.om.ScarabUser#getMostRecentQuery()
1309     */

1310    public String JavaDoc getMostRecentQuery()
1311    {
1312        return getMostRecentQuery(getGenThreadKey());
1313    }
1314    private String JavaDoc getMostRecentQuery(Object JavaDoc key)
1315    {
1316        setCurrentMITList(key, (MITList)mostRecentQueryMITMap.get(key));
1317        return (String JavaDoc)mostRecentQueryMap.get(key);
1318    }
1319
1320    /**
1321     * @see org.tigris.scarab.om.ScarabUser#setMostRecentQuery(String)
1322     */

1323    public void setMostRecentQuery(String JavaDoc queryString)
1324    {
1325        if (queryString != null)
1326        {
1327            setMostRecentQuery(getGenThreadKey(), queryString);
1328        }
1329        else if (getThreadKey() != null)
1330        {
1331            setMostRecentQuery(getThreadKey(), null);
1332        }
1333    }
1334    private void setMostRecentQuery(Object JavaDoc key, String JavaDoc queryString)
1335    {
1336        if (queryString == null)
1337        {
1338            mostRecentQueryMap.remove(key);
1339            mostRecentQueryMITMap.remove(key);
1340        }
1341        else
1342        {
1343            try
1344            {
1345                if (mostRecentQueryMap.size() >= MAX_INDEPENDENT_WINDOWS)
1346                {
1347                    // make sure lists are not being accumulated, set a
1348
// reasonable limit of MAX_INDEPENDENT_WINDOWS open lists
1349
int intKey = Integer.parseInt(String.valueOf(key));
1350                    int count = 0;
1351                    for (int i=intKey-1; i>=0; i--)
1352                    {
1353                        String JavaDoc testKey = String.valueOf(i);
1354                        if (getMostRecentQuery(testKey) != null)
1355                        {
1356                            if (++count >= MAX_INDEPENDENT_WINDOWS)
1357                            {
1358                                mostRecentQueryMap.remove(testKey);
1359                                mostRecentQueryMITMap.remove(testKey);
1360                            }
1361                        }
1362                    }
1363                }
1364            }
1365            catch (Exception JavaDoc e)
1366            {
1367                Log.get().error("Nonfatal error clearing old queries. "
1368                                + "This could be a memory leak.", e);
1369            }
1370            MITList list = getCurrentMITList(key);
1371            if (list != null)
1372            {
1373                mostRecentQueryMITMap.put(key, list);
1374                mostRecentQueryMap.put(key, queryString);
1375            }
1376            else
1377            {
1378                Log.get().warn(
1379                    "Tried to set most recent query without any mitlist.");
1380            }
1381        }
1382    }
1383
1384
1385    public Object JavaDoc lastEnteredIssueTypeOrTemplate()
1386    {
1387        return lastEnteredIssueTypeOrTemplate(getGenThreadKey());
1388    }
1389    private Object JavaDoc lastEnteredIssueTypeOrTemplate(Object JavaDoc key)
1390    {
1391        Log.get().debug("Getting last entered type for key " + key);
1392        return enterIssueMap.get(key);
1393    }
1394
1395
1396    /**
1397     * @see org.tigris.scarab.om.ScarabUser#setLastEnteredIssueType(IssueType)
1398     */

1399    public void setLastEnteredIssueType(IssueType type)
1400    {
1401        setLastEnteredIssueTypeOrTemplate(type);
1402    }
1403    /**
1404     * @see org.tigris.scarab.om.ScarabUser#setLastEnteredTemplate(Issue)
1405     */

1406    public void setLastEnteredTemplate(Issue template)
1407    {
1408        setLastEnteredIssueTypeOrTemplate(template);
1409    }
1410    /**
1411     * set the template or issue type
1412     */

1413    private void setLastEnteredIssueTypeOrTemplate(Object JavaDoc obj)
1414    {
1415        if (obj != null)
1416        {
1417            setLastEnteredIssueTypeOrTemplate(getGenThreadKey(), obj);
1418        }
1419        else if (getThreadKey() != null)
1420        {
1421            setLastEnteredIssueTypeOrTemplate(getThreadKey(), null);
1422        }
1423    }
1424    private void setLastEnteredIssueTypeOrTemplate(Object JavaDoc key, Object JavaDoc obj)
1425    {
1426        if (obj == null)
1427        {
1428            enterIssueMap.remove(key);
1429        }
1430        else
1431        {
1432            try
1433            {
1434                if (enterIssueMap.size() >= MAX_INDEPENDENT_WINDOWS)
1435                {
1436                    // make sure lists are not being accumulated, set a
1437
// reasonable limit of MAX_INDEPENDENT_WINDOWS open lists
1438
int intKey = Integer.parseInt(String.valueOf(key));
1439                    int count = 0;
1440                    for (int i=intKey-1; i>=0; i--)
1441                    {
1442                        String JavaDoc testKey = String.valueOf(i);
1443                        if (lastEnteredIssueTypeOrTemplate(testKey) != null)
1444                        {
1445                            if (++count >= MAX_INDEPENDENT_WINDOWS)
1446                            {
1447                                enterIssueMap.remove(testKey);
1448                            }
1449                        }
1450                    }
1451                }
1452            }
1453            catch (Exception JavaDoc e)
1454            {
1455                Log.get().error("Nonfatal error clearing entered issue types. "
1456                                + "This could be a memory leak.", e);
1457            }
1458            Log.get().debug("Set issue type for key " + key + " to " + obj);
1459            
1460            enterIssueMap.put(key, obj);
1461        }
1462    }
1463
1464
1465    private void setUsersMap(Map JavaDoc map, Map JavaDoc users)
1466        throws Exception JavaDoc
1467    {
1468        Object JavaDoc key = (users != null ? getGenThreadKey() : getThreadKey());
1469        if (key == null)
1470        {
1471            // With no hash key, this method won't work.
1472
return;
1473        }
1474
1475        if (users != null && users.size() >= MAX_INDEPENDENT_WINDOWS)
1476        {
1477            try
1478            {
1479                // Set a reasonable limit on the number of open lists.
1480
int intKey = Integer.parseInt(String.valueOf(key));
1481                int count = 0;
1482                for (int i = intKey - 1; i >= 0; i--)
1483                {
1484                    String JavaDoc testKey = String.valueOf(i);
1485                    if (map.get(testKey) != null)
1486                    {
1487                        if (++count >= MAX_INDEPENDENT_WINDOWS)
1488                        {
1489                            users.remove(testKey);
1490                        }
1491                    }
1492                }
1493            }
1494            catch (Exception JavaDoc e)
1495            {
1496                // FIXME: I18N
1497
Log.get().warn("Error possibly resulting in memory leak", e);
1498            }
1499        }
1500
1501        map.put(key, users);
1502    }
1503
1504    /**
1505     * @see org.tigris.scarab.om.ScarabUser#getAssociatedUsersMap()
1506     */

1507    public Map JavaDoc getAssociatedUsersMap()
1508        throws Exception JavaDoc
1509    {
1510        return (Map JavaDoc) associatedUsersMap.get(getGenThreadKey());
1511    }
1512
1513    /**
1514     * @see org.tigris.scarab.om.ScarabUser#setAssociatedUsersMap(Map)
1515     */

1516    public void setAssociatedUsersMap(Map JavaDoc associatedUsers)
1517        throws Exception JavaDoc
1518    {
1519        setUsersMap(associatedUsersMap, associatedUsers);
1520    }
1521
1522    /**
1523     * @see org.tigris.scarab.om.ScarabUser#getSelectedUsersMap()
1524     */

1525    public Map JavaDoc getSelectedUsersMap()
1526        throws Exception JavaDoc
1527    {
1528        return (Map JavaDoc) selectedUsersMap.get(getGenThreadKey());
1529    }
1530
1531    /**
1532     * @see org.tigris.scarab.om.ScarabUser#setSelectedUsersMap(Map)
1533     */

1534    public void setSelectedUsersMap(Map JavaDoc selectedUsers)
1535        throws Exception JavaDoc
1536    {
1537        setUsersMap(selectedUsersMap, selectedUsers);
1538    }
1539
1540    /**
1541     * The current module
1542     */

1543    public Module getCurrentModule()
1544    {
1545        return (Module)currentModule.get();
1546    }
1547    
1548    /**
1549     * The current module
1550     */

1551    public void setCurrentModule(Module v)
1552    {
1553        this.currentModule.set(v);
1554    }
1555     
1556    /**
1557     * The current issue type
1558     */

1559    public IssueType getCurrentIssueType()
1560        throws Exception JavaDoc
1561    {
1562        return (IssueType)currentIssueType.get();
1563    }
1564    
1565    /**
1566     * The current issue type
1567     */

1568    public void setCurrentIssueType(IssueType v)
1569    {
1570        this.currentIssueType.set(v);
1571    }
1572    
1573    /**
1574     * @see ScarabUser#getCurrentRModuleIssueType()
1575     */

1576    public RModuleIssueType getCurrentRModuleIssueType()
1577        throws Exception JavaDoc
1578    {
1579        RModuleIssueType rmit = null;
1580        Module module = getCurrentModule();
1581        if (module != null)
1582        {
1583            IssueType it = getCurrentIssueType();
1584            if (it != null)
1585            {
1586                rmit = module.getRModuleIssueType(it);
1587            }
1588        }
1589        
1590        return rmit;
1591    }
1592
1593
1594    /**
1595     * @see org.tigris.scarab.om.ScarabUser#updateIssueListAttributes(List)
1596     */

1597    public void updateIssueListAttributes(List JavaDoc attributes)
1598        throws Exception JavaDoc
1599    {
1600        MITList mitList = getCurrentMITList();
1601
1602        // Delete current attribute selections for user
1603
for (Iterator JavaDoc currentAttributes = mitList.getSavedRMUAs().iterator();
1604               currentAttributes.hasNext();)
1605        {
1606            deleteRModuleUserAttribute(
1607                (RModuleUserAttribute)currentAttributes.next());
1608        }
1609
1610        int i = 1;
1611        for (Iterator JavaDoc iter = attributes.iterator(); iter.hasNext();)
1612        {
1613            Attribute attribute = (Attribute)iter.next();
1614            RModuleUserAttribute rmua =
1615                mitList.getNewRModuleUserAttribute(attribute);
1616            rmua.setOrder(i++);
1617            rmua.save();
1618        }
1619    }
1620
1621    protected abstract void
1622        deleteRModuleUserAttribute(RModuleUserAttribute rmua)
1623        throws Exception JavaDoc;
1624
1625
1626    /**
1627     * Report the sizes of maps used to hold per-thread attributes
1628     */

1629    public String JavaDoc getStats()
1630    {
1631        return " IssueMap=" + issueMap.size()
1632            + "; ReportMap=" + reportMap.size()
1633            + "; MITListMap=" + mitListMap.size()
1634            + "; MostRecentQueryMap=" + mostRecentQueryMap.size()
1635            + "; MostRecentQueryMITMap=" + mostRecentQueryMITMap.size()
1636            + "; EnterIssueMap=" + enterIssueMap.size();
1637    }
1638
1639    /**
1640     * Set the user's locale to a new value.
1641     */

1642    public void setLocale(Locale JavaDoc newLocale)
1643    {
1644        locale = newLocale;
1645    }
1646
1647    /**
1648     * Gets the users default locale from the users preferences.
1649     */

1650    public Locale JavaDoc getLocale()
1651    {
1652        if (locale == null)
1653        {
1654            locale = getPreferredLocale();
1655        }
1656        return locale;
1657    }
1658
1659    /**
1660     * get preferred Locale from user preferences
1661     * @return
1662     */

1663    public Locale JavaDoc getPreferredLocale()
1664    {
1665        Locale JavaDoc result;
1666        try
1667        {
1668            UserPreference up =
1669                UserPreferenceManager.getInstance(getUserId());
1670            result = Localization.getLocale(up.getLocale());
1671        }
1672        catch (Exception JavaDoc e)
1673        {
1674            // I think it might be ok to return null from this method
1675
// but until that is investigated return the default in
1676
// event of error
1677
result = ScarabConstants.DEFAULT_LOCALE;
1678            Log.get().warn(
1679                "AbstractScarabUser.getLocale() could not "
1680                    + "retrieve locale for user id="
1681                    + getUserId()
1682                    + "; Error message: "
1683                    + e.getMessage());
1684        }
1685        return result;
1686    }
1687
1688
1689    /**
1690     * @see org.tigris.scarab.om.ScarabUser#isShowOtherModulesInIssueTypeList()
1691     */

1692    public boolean isShowOtherModulesInIssueTypeList()
1693    {
1694        return showOtherModulesInIssueTypeList;
1695    }
1696
1697    /**
1698     * @see org.tigris.scarab.om.ScarabUser#setShowOtherModulesInIssueTypeList(boolean)
1699     */

1700    public void setShowOtherModulesInIssueTypeList(
1701        boolean newShowOtherModulesInIssueTypeList)
1702    {
1703        this.showOtherModulesInIssueTypeList =
1704            newShowOtherModulesInIssueTypeList;
1705    }
1706}
1707
Popular Tags