001: /***************************************************************
002: * This file is part of the [fleXive](R) project.
003: *
004: * Copyright (c) 1999-2007
005: * UCS - unique computing solutions gmbh (http://www.ucs.at)
006: * All rights reserved
007: *
008: * The [fleXive](R) project is free software; you can redistribute
009: * it and/or modify it under the terms of the GNU General Public
010: * License as published by the Free Software Foundation;
011: * either version 2 of the License, or (at your option) any
012: * later version.
013: *
014: * The GNU General Public License can be found at
015: * http://www.gnu.org/copyleft/gpl.html.
016: * A copy is found in the textfile GPL.txt and important notices to the
017: * license from the author are found in LICENSE.txt distributed with
018: * these libraries.
019: *
020: * This library is distributed in the hope that it will be useful,
021: * but WITHOUT ANY WARRANTY; without even the implied warranty of
022: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
023: * GNU General Public License for more details.
024: *
025: * For further information about UCS - unique computing solutions gmbh,
026: * please see the company website: http://www.ucs.at
027: *
028: * For further information about [fleXive](R), please see the
029: * project website: http://www.flexive.org
030: *
031: *
032: * This copyright notice MUST APPEAR in all copies of the file!
033: ***************************************************************/package com.flexive.war.beans.admin.main;
034:
035: import com.flexive.faces.FxJsfUtils;
036: import com.flexive.faces.messages.FxFacesMsgErr;
037: import com.flexive.faces.messages.FxFacesMsgInfo;
038: import com.flexive.shared.EJBLookup;
039: import com.flexive.shared.FxArrayUtils;
040: import com.flexive.shared.FxContext;
041: import com.flexive.shared.content.FxContent;
042: import com.flexive.shared.exceptions.FxApplicationException;
043: import com.flexive.shared.interfaces.AccountEngine;
044: import com.flexive.shared.interfaces.ContentEngine;
045: import com.flexive.shared.interfaces.UserGroupEngine;
046: import com.flexive.shared.security.*;
047: import com.flexive.war.FxRequest;
048: import org.apache.commons.lang.StringUtils;
049: import org.apache.commons.logging.Log;
050: import org.apache.commons.logging.LogFactory;
051:
052: import javax.faces.component.UISelectBoolean;
053: import javax.faces.model.SelectItem;
054: import java.text.SimpleDateFormat;
055: import java.util.*;
056:
057: /**
058: * Management of accounts.
059: *
060: * @author Gregor Schober (gregor.schober@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
061: * @version $Rev: 1418 $
062: */
063: public class AccountBean {
064: private static final Log LOG = LogFactory.getLog(AccountBean.class);
065:
066: private UISelectBoolean activeFilterCheckbox;
067: private UISelectBoolean validatedFilterCheckbox;
068:
069: private long groupFilter = -1;
070: private long accountIdFiler = -1;
071: private AccountEngine accountInterface;
072: private boolean activeFilter = true;
073: private boolean validatedFilter = true;
074: private String password;
075: private String passwordConfirm;
076: private Account account;
077: private final SimpleDateFormat SDF = new SimpleDateFormat(
078: "dd-MM-yyyy");
079: private List<UserGroup> groups;
080: private List<Role> roles;
081: private Mandator mandator;
082: private Hashtable<String, ArrayList<Account>> listCache;
083: private static final String ID_CACHE_KEY = AccountBean.class
084: + "_id";
085: private ContentEngine contentInterface;
086: private FxContent contactData;
087:
088: public List<Role> getRoles() {
089: return roles == null ? new ArrayList<Role>(0) : roles;
090: }
091:
092: /**
093: * Getter for roles implicitly set from groups
094: *
095: * @return roles implicitly set from groups
096: * @throws FxApplicationException on errors
097: */
098: public List<Role> getRolesGroups() throws FxApplicationException {
099: if (groups == null)
100: return new ArrayList<Role>(0);
101: List<Role> result = new ArrayList<Role>(Role.values().length);
102: for (UserGroup grp : groups) {
103: List<Role> tmp = EJBLookup.getUserGroupEngine().getRoles(
104: grp.getId()).getList();
105: result.removeAll(tmp);
106: result.addAll(tmp);
107: }
108: return result;
109: }
110:
111: public void setRoles(List<Role> roles) {
112: this .roles = roles;
113: }
114:
115: public List<UserGroup> getGroups() {
116: return groups == null ? new ArrayList<UserGroup>(0) : groups;
117: }
118:
119: public void setGroups(List<UserGroup> groups) {
120: this .groups = groups;
121: }
122:
123: public long getAccountIdFiler() {
124: return accountIdFiler;
125: }
126:
127: public void setAccountIdFiler(long accountIdFiler) {
128: this .accountIdFiler = accountIdFiler;
129: FxJsfUtils.setSessionAttribute(ID_CACHE_KEY,
130: this .accountIdFiler);
131: }
132:
133: /**
134: * Constructor.
135: */
136: public AccountBean() {
137: accountInterface = EJBLookup.getAccountEngine();
138: listCache = new Hashtable<String, ArrayList<Account>>(5);
139: resetFilter();
140: }
141:
142: private void resetAccount() {
143: account = new Account();
144: }
145:
146: private void resetFilter() {
147: resetAccount();
148: groupFilter = -1;
149: groups = null;
150: roles = null;
151: activeFilter = true;
152: validatedFilter = true;
153: try {
154: // Default valid from: Today, but delete time part
155: account.setValidFrom(SDF.parse(SDF.format(new Date())));
156: // Default valid to: Way in the future
157: account.setValidTo(SDF.parse("01-01-3000"));
158: } catch (Exception exc) {
159: new FxFacesMsgErr(exc).addToContext();
160: }
161: }
162:
163: public boolean isActiveFilter() {
164: if (activeFilterCheckbox != null
165: && activeFilterCheckbox.getSubmittedValue() != null) {
166: // use submitted value during postbacks to apply the correct filters
167: return Boolean.parseBoolean((String) activeFilterCheckbox
168: .getSubmittedValue());
169: }
170: return activeFilter;
171: }
172:
173: public void setActiveFilter(boolean activeFilter) {
174: this .activeFilter = activeFilter;
175: }
176:
177: public boolean isValidatedFilter() {
178: if (validatedFilterCheckbox != null
179: && validatedFilterCheckbox.getSubmittedValue() != null) {
180: // use submitted value during postbacks to apply the correct filters
181: return Boolean
182: .parseBoolean((String) validatedFilterCheckbox
183: .getSubmittedValue());
184: }
185: return validatedFilter;
186: }
187:
188: public void setValidatedFilter(boolean validatedFilter) {
189: this .validatedFilter = validatedFilter;
190: }
191:
192: public Mandator getMandator() {
193: return mandator;
194: }
195:
196: public void setMandator(Mandator mandator) {
197: this .mandator = mandator;
198: this .account.setMandatorId(mandator == null ? -1 : mandator
199: .getId());
200: }
201:
202: public long getGroupFilter() {
203: return groupFilter;
204: }
205:
206: public void setGroupFilter(long groupFilter) {
207: this .groupFilter = groupFilter;
208: }
209:
210: public String getPassword() {
211: return password;
212: }
213:
214: public void setPassword(String password) {
215: this .password = password;
216: }
217:
218: public String getPasswordConfirm() {
219: return passwordConfirm;
220: }
221:
222: public void setPasswordConfirm(String passwordConfirm) {
223: this .passwordConfirm = passwordConfirm;
224: }
225:
226: public Account getAccount() {
227: return account;
228: }
229:
230: public void setAccount(Account account) {
231: this .account = account;
232: }
233:
234: public UISelectBoolean getActiveFilterCheckbox() {
235: return activeFilterCheckbox;
236: }
237:
238: public void setActiveFilterCheckbox(
239: UISelectBoolean activeFilterCheckbox) {
240: this .activeFilterCheckbox = activeFilterCheckbox;
241: }
242:
243: public UISelectBoolean getValidatedFilterCheckbox() {
244: return validatedFilterCheckbox;
245: }
246:
247: public void setValidatedFilterCheckbox(
248: UISelectBoolean validatedFilterCheckbox) {
249: this .validatedFilterCheckbox = validatedFilterCheckbox;
250: }
251:
252: /**
253: * Returns all user groups defined for the current mandator that are not flagged as system.
254: *
255: * @return all user groups defined for the current mandator.
256: * @throws FxApplicationException if the user groups could not be fetched successfully.
257: */
258: public List<SelectItem> getFilteredUserGroups()
259: throws FxApplicationException {
260: long mandatorId;
261: if (getAccount().isNew()) {
262: if (getMandator() == null)
263: return new ArrayList<SelectItem>(0);
264: else
265: mandatorId = getMandator().getId();
266: } else
267: mandatorId = getAccount().getMandatorId();
268: UserGroupEngine groupEngine = EJBLookup.getUserGroupEngine();
269: List<UserGroup> groups = groupEngine.loadAll(mandatorId)
270: .getList();
271: List<SelectItem> userGroupsNonSystem = new ArrayList<SelectItem>(
272: groups.size());
273: for (UserGroup group : groups) {
274: if (group.isSystem())
275: continue;
276: userGroupsNonSystem.add(new SelectItem(group, group
277: .getName()));
278: }
279: return userGroupsNonSystem;
280: }
281:
282: public String getParseRequestParameters() {
283: try {
284: String action = FxJsfUtils.getParameter("action");
285: if (StringUtils.isBlank(action)) {
286: // no action requested
287: return null;
288: }
289: // hack!
290: FxJsfUtils.resetFaceletsComponent("listForm");
291:
292: if ("editUserPref".equals(action)) {
293: editUserPref();
294: }
295: } catch (Exception e) {
296: // TODO possibly pass some error message to the HTML page
297: LOG.error("Failed to parse request parameters: "
298: + e.getMessage(), e);
299: }
300: return null;
301: }
302:
303: public String showContactData() {
304: FxRequest request = FxJsfUtils.getRequest();
305: if (this .account.getContactData() != null) {
306: request.setAttribute("cdId", this .account.getContactData()
307: .getId());
308: request.setAttribute("vers", this .account.getContactData()
309: .getVersion());
310: } else {
311: request.setAttribute("cdId", -1);
312: request.setAttribute("vers", -1);
313: }
314: return "showContentEditor";
315: }
316:
317: /**
318: * Deletes a user, with the id specified by accountIdFiler.
319: *
320: * @return the next pageto render
321: */
322: public String deleteUser() {
323: try {
324: ensureAccountIdSet();
325: accountInterface.remove(accountIdFiler);
326: new FxFacesMsgInfo("User.nfo.deleted").addToContext();
327: listCache.clear();
328: resetFilter();
329: } catch (Exception exc) {
330: resetAccount();
331: new FxFacesMsgErr(exc).addToContext();
332: }
333: return "accountOverview";
334: }
335:
336: private void ensureAccountIdSet() {
337: if (this .accountIdFiler <= 0) {
338: this .accountIdFiler = (Long) FxJsfUtils
339: .getSessionAttribute(ID_CACHE_KEY);
340: }
341: }
342:
343: /**
344: * Loads the user specified by the parameter accountIdFilter.
345: *
346: * @return the next page to render
347: */
348: public String editUser() {
349: try {
350: ensureAccountIdSet();
351: this .account = accountInterface.load(this .accountIdFiler);
352: this .roles = accountInterface.getRoleList(
353: this .accountIdFiler,
354: AccountEngine.RoleLoadMode.FROM_USER_ONLY);
355: this .groups = accountInterface
356: .getGroupList(this .accountIdFiler);
357: return "accountEdit";
358: } catch (Throwable t) {
359: new FxFacesMsgErr(t).addToContext();
360: return "accountEdit";
361: }
362: }
363:
364: /**
365: * Loads the account of the current user
366: *
367: * @return the next page to render
368: */
369: public String editUserPref() {
370: try {
371: this .account = accountInterface.load(FxContext.get()
372: .getTicket().getUserId());
373: setAccountIdFiler(this .account.getId());
374: this .roles = accountInterface
375: .getRoleList(this .accountIdFiler,
376: AccountEngine.RoleLoadMode.ALL);
377: this .groups = accountInterface
378: .getGroupList(this .accountIdFiler);
379: this .contactData = null;
380: try {
381: this .contactData = EJBLookup.getContentEngine().load(
382: this .account.getContactData());
383: } catch (NullPointerException ex) {
384: // ...
385: }
386: return "userEdit";
387: } catch (Throwable t) {
388: new FxFacesMsgErr(t).addToContext();
389: return "contentPage";
390: }
391: }
392:
393: public FxContent getContactData() {
394: return contactData;
395: }
396:
397: /**
398: * Navigate back to the overview and reset all form data
399: *
400: * @return overview oage
401: */
402: public String overview() {
403: //keep filter but reset account data
404: resetAccount();
405: return "accountOverview";
406: }
407:
408: /**
409: * save the user settings
410: *
411: * @return content page
412: */
413: public String saveUserPref() {
414: try {
415: String newPasswd = null;
416:
417: // Determine if the password must be set
418: if (password != null && password.trim().length() > 0) {
419: if (!password.equals(passwordConfirm)) {
420: new FxFacesMsgErr("User.err.passwordsDontMatch")
421: .addToContext();
422: return editUserPref();
423: }
424: newPasswd = password;
425: }
426: accountInterface.updateUser(this .accountIdFiler, newPasswd,
427: null, null, this .account.getEmail(), this .account
428: .getLanguage().getId());
429: new FxFacesMsgInfo("User.nfo.settingsSaved").addToContext();
430: } catch (FxApplicationException e) {
431: new FxFacesMsgErr("User.err.settingsNotSaved")
432: .addToContext();
433: new FxFacesMsgErr(e).addToContext();
434: return editUserPref();
435: }
436: return "contentPage";
437: }
438:
439: public String saveUser() {
440: try {
441: String newPasswd = null;
442:
443: // Determine if the password must be set
444: if (password != null && password.trim().length() > 0) {
445: if (!password.equals(passwordConfirm)) {
446: new FxFacesMsgErr("User.err.passwordsDontMatch")
447: .addToContext();
448: return "accountEdit";
449: }
450: newPasswd = password;
451: }
452:
453: // Update the user
454: accountInterface.update(this .accountIdFiler, newPasswd,
455: null, null, null, this .account.getEmail(),
456: this .account.isValidated(),
457: this .account.isActive(), this .account
458: .getValidFrom(), this .account.getValidTo(),
459: this .account.getLanguage().getId(), this .account
460: .getDescription(), this .account
461: .isAllowMultiLogin(), this .account
462: .getContactData().getId());
463: new FxFacesMsgInfo("User.nfo.saved").addToContext();
464: // Assign the given groups to the account
465: try {
466: accountInterface.setGroupList(this .accountIdFiler,
467: groups);
468: } catch (Exception exc) {
469: new FxFacesMsgErr(exc).addToContext();
470: }
471:
472: // Assign the given roles to the account
473: try {
474: accountInterface.setRoleList(this .accountIdFiler,
475: getRoles());
476: } catch (Exception exc) {
477: new FxFacesMsgErr(exc).addToContext();
478: }
479: // Reload and display
480: return editUser();
481: } catch (Throwable t) {
482: new FxFacesMsgErr(t).addToContext();
483: return "accountEdit";
484: }
485: }
486:
487: /**
488: * Creates a new user from the beans data.
489: *
490: * @return the next jsf page to render
491: */
492: public String createUser() {
493:
494: boolean hasError = false;
495:
496: // Param check
497: if (password == null) {
498: password = "";
499: }
500:
501: // Passwords must match
502: if (!password.equals(passwordConfirm)) {
503: new FxFacesMsgErr("User.err.passwordsDontMatch")
504: .addToContext();
505: hasError = true;
506: }
507:
508: // Mandator select and check
509: final UserTicket ticket = FxContext.get().getTicket();
510: long mandatorId = ticket.isGlobalSupervisor() ? account
511: .getMandatorId() : ticket.getMandatorId();
512: if (mandatorId < 0) {
513: FxFacesMsgErr msg = new FxFacesMsgErr(
514: "User.err.mandatorMissing");
515: msg.setId("mandator");
516: msg.addToContext();
517: hasError = true;
518: }
519:
520: // If we have an error abort
521: if (hasError) {
522: return "accountCreate";
523: }
524:
525: // Create the new account itself
526: try {
527: setAccountIdFiler(accountInterface.create(
528: account.getName(), account.getLoginName(),
529: password, account.getEmail(), account.getLanguage()
530: .getId(), mandatorId, account.isActive(),
531: account.isValidated(), account.getValidFrom(),
532: account.getValidTo(), -1, account.getDescription(),
533: false, true));
534: account = accountInterface.load(this .accountIdFiler);
535: new FxFacesMsgInfo("User.nfo.saved", account.getName())
536: .addToContext();
537: } catch (Exception exc) {
538: new FxFacesMsgErr(exc).addToContext();
539: return "accountCreate";
540: }
541:
542: // Assign the given groups to the account
543: try {
544: accountInterface.setGroupList(this .accountIdFiler, groups);
545: } catch (Exception exc) {
546: new FxFacesMsgErr(exc).addToContext();
547: }
548:
549: // Assign the given roles to the account
550: try {
551: accountInterface.setRoleList(this .accountIdFiler,
552: getRoles());
553: } catch (Exception exc) {
554: new FxFacesMsgErr(exc).addToContext();
555: }
556: listCache.clear();
557: resetFilter();
558:
559: return "accountOverview";
560: }
561:
562: /**
563: * Retrieves all users, filtering by loginName, userName, email, active, vaidated and mandatorFilter.
564: *
565: * @return all users matching the filter criterias.
566: */
567: public ArrayList<Account> getList() {
568: final UserTicket ticket = FxContext.get().getTicket();
569: try {
570: long _mandatorFilter = mandator == null ? -1 : mandator
571: .getId();
572:
573: // If not supervisor fallback to the own mandator
574: if (!ticket.isGlobalSupervisor()) {
575: _mandatorFilter = ticket.getMandatorId();
576: }
577:
578: long[] userGroupIds = new long[1];
579: if (groupFilter != -1) {
580: userGroupIds[0] = groupFilter;
581: } else {
582: userGroupIds = null;
583: }
584:
585: // Load list if needed, and cache within the request
586: String cacheKey = account.getName() + "_"
587: + account.getLoginName() + "_" + account.getEmail()
588: + "_" + isActiveFilter() + "_"
589: + isValidatedFilter() + "_" + _mandatorFilter + "_"
590: + FxArrayUtils.toSeparatedList(userGroupIds, ',');
591: ArrayList<Account> result = listCache.get(cacheKey);
592: if (result == null) {
593: Account allUsers[] = accountInterface.loadAll(account
594: .getName(), account.getLoginName(), account
595: .getEmail(), isActiveFilter(),
596: isValidatedFilter(), _mandatorFilter, null,
597: userGroupIds, 0, -1);
598: result = new ArrayList<Account>(allUsers.length);
599: result.addAll(Arrays.asList(allUsers));
600: listCache.put(cacheKey, result);
601: }
602: return result;
603:
604: } catch (Exception exc) {
605: new FxFacesMsgErr(exc).addToContext();
606: return new ArrayList<Account>(0);
607: }
608: }
609:
610: }
|