001: /*
002: * $Header: /export/home/cvsroot/MyPersonalizerRepository/MyPersonalizer/Subsystems/Portal/Sources/es/udc/mypersonalizer/portal/model/actions/user/SignUpAction.java,v 1.1.1.1 2004/03/25 12:08:40 fbellas Exp $
003: * $Revision: 1.1.1.1 $
004: * $Date: 2004/03/25 12:08:40 $
005: *
006: * =============================================================================
007: *
008: * Copyright (c) 2003, The MyPersonalizer Development Group
009: * (http://www.tic.udc.es/~fbellas/mypersonalizer/index.html) at
010: * University Of A Coruna
011: * All rights reserved.
012: *
013: * Redistribution and use in source and binary forms, with or without
014: * modification, are permitted provided that the following conditions are met:
015: *
016: * - Redistributions of source code must retain the above copyright notice,
017: * this list of conditions and the following disclaimer.
018: *
019: * - Redistributions in binary form must reproduce the above copyright notice,
020: * this list of conditions and the following disclaimer in the documentation
021: * and/or other materials provided with the distribution.
022: *
023: * - Neither the name of the University Of A Coruna nor the names of its
024: * contributors may be used to endorse or promote products derived from
025: * this software without specific prior written permission.
026: *
027: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
028: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
029: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
030: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
031: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
032: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
033: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
034: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
035: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
036: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
037: * POSSIBILITY OF SUCH DAMAGE.
038: *
039: */
040:
041: package es.udc.mypersonalizer.portal.model.actions.user;
042:
043: import es.udc.mypersonalizer.kernel.conventions.UserAndGroupConventions;
044: import es.udc.mypersonalizer.kernel.model.actions.AbstractAction;
045: import es.udc.mypersonalizer.kernel.model.actions.ActionProcessorSingleton;
046: import es.udc.mypersonalizer.kernel.model.editors.DesktopLayoutEditor;
047: import es.udc.mypersonalizer.kernel.model.editors.EditorFactory;
048: import es.udc.mypersonalizer.kernel.model.editors.UserRegistrationInformationEditor;
049: import es.udc.mypersonalizer.kernel.model.editors.WorkspaceLayoutEditor;
050: import es.udc.mypersonalizer.kernel.model.properties.Property;
051: import es.udc.mypersonalizer.kernel.model.repository.interfaces.DesktopLayout;
052: import es.udc.mypersonalizer.kernel.model.repository.interfaces.DesktopLayoutAccessor;
053: import es.udc.mypersonalizer.kernel.model.repository.interfaces.RepositoryAccessorFactory;
054: import es.udc.mypersonalizer.kernel.model.repository.interfaces.UserGroupAccessor;
055: import es.udc.mypersonalizer.kernel.model.repository.interfaces.UserRegistrationInformation;
056: import es.udc.mypersonalizer.kernel.model.repository.interfaces.UserRegistrationInformationAccessor;
057: import es.udc.mypersonalizer.kernel.model.repository.interfaces.WorkspaceLayout;
058: import es.udc.mypersonalizer.kernel.model.repository.interfaces.WorkspaceLayoutAccessor;
059: import es.udc.mypersonalizer.kernel.util.exceptions.DuplicateInstanceException;
060: import es.udc.mypersonalizer.kernel.util.exceptions.InstanceNotFoundException;
061: import es.udc.mypersonalizer.kernel.util.exceptions.InternalErrorException;
062: import es.udc.mypersonalizer.kernel.util.general.Cloner;
063: import es.udc.mypersonalizer.portal.model.encryption.PasswordManagerSingleton;
064: import es.udc.mypersonalizer.portal.model.permissions.PermissionCheckerSingleton;
065: import es.udc.mypersonalizer.portal.model.permissions.UserCredentials;
066: import es.udc.mypersonalizer.portal.model.types.WizardEvent;
067: import es.udc.mypersonalizer.portal.model.types.content.AddWorkspaceEvent;
068: import es.udc.mypersonalizer.portal.model.types.content.AddWorkspaceResult;
069: import es.udc.mypersonalizer.portal.model.types.user.SignInResult;
070: import es.udc.mypersonalizer.portal.model.wizards.PropertyUpdater;
071: import es.udc.mypersonalizer.portal.model.wizards.PropertyUpdaterRegistrySingleton;
072: import java.io.Serializable;
073: import java.util.*;
074:
075: /**
076: * This action class performs a user sign up, this is, adds a new user to
077: * the system. To do so, it has to perform the following steps:
078: * <ol>
079: * <li>Add the <b>user's registration information</b> to the repository,
080: * being added to the groups specified in the {@link UserCredentials}
081: * object that is part of the event.</li>
082: * <li>Create a new <b>desktop layout</b> for this user, being cloned for
083: * the one the <tt>mypersonalizer</tt> user has.</li>
084: * <li>Clone all the <b>workspaces</b> from the <tt>mypersonalizer</tt> user,
085: * ignoring those for which this user has no permissions. The default
086: * workspace for the <tt>mypersonalizer</tt> user will also be set
087: * as default for the new user, if he / she has permissions for it.</li>
088: * <li>For each workspace being added to the user's desktop lyaout, add
089: * all of the <b>services</b> the <tt>mypersonalizer</tt> user has
090: * in them, in the same area and position. The personalization information
091: * for these services will be built using the associated ServicePrototype
092: * and applying the correspondend ServiceModel action to it.</li>
093: * </ol>
094: *
095: * In fact, the third and fourth steps are performed by calling the model
096: * action <tt>AddWorkspaceAction</tt>, which is in charge of
097: * creating the new workpaces the correct way. This action must be registered
098: * in the configuration.<p>
099: *
100: * This action returns a {@link SignInResult} object, correctly filled with the
101: * user's information. See the result class documentation for further explaining
102: * about the returning data.
103: *
104: * @author Daniel Fernandez
105: * @since 1.0
106: */
107: public class SignUpAction extends AbstractAction {
108:
109: /**
110: * Name of the model action for adding a workspace.
111: * This is "AddWorkspaceAction".
112: */
113: private static final String ADD_WORKSPACE_ACTION = "AddWorkspaceAction";
114:
115: public Serializable execute(Serializable event)
116: throws InternalErrorException, DuplicateInstanceException {
117:
118: WizardEvent signUpEvent = (WizardEvent) event;
119:
120: UserCredentials userCredentials = signUpEvent
121: .getUserCredentials();
122: String propertyUpdaterName = signUpEvent
123: .getPropertyUpdaterName();
124:
125: try {
126:
127: /* Accessors */
128: RepositoryAccessorFactory repositoryAccessorFactory = RepositoryAccessorFactory
129: .getInstance();
130:
131: UserRegistrationInformationAccessor userRegistrationInformationAccessor = repositoryAccessorFactory
132: .createUserRegistrationInformationAccessor();
133:
134: DesktopLayoutAccessor desktopLayoutAccessor = repositoryAccessorFactory
135: .createDesktopLayoutAccessor();
136:
137: WorkspaceLayoutAccessor workspaceLayoutAccessor = repositoryAccessorFactory
138: .createWorkspaceLayoutAccessor();
139:
140: /* Editor Factory */
141: EditorFactory editorFactory = EditorFactory.getInstance();
142:
143: /* Singletons */
144: PermissionCheckerSingleton permissionCheckerSingleton = PermissionCheckerSingleton
145: .getInstance();
146:
147: PropertyUpdaterRegistrySingleton propertyUpdaterRegistrySingleton = PropertyUpdaterRegistrySingleton
148: .getInstance();
149:
150: PasswordManagerSingleton passwordManagerSingleton = PasswordManagerSingleton
151: .getInstance();
152:
153: ActionProcessorSingleton actionProcessorSingleton = ActionProcessorSingleton
154: .getInstance();
155:
156: /*
157: * We will need the UserRegistrationInformation for the
158: * "mypersonalizer" user, so as to (later) copy the workspaces and
159: * services in them for the new user (only the allowed ones)
160: */
161: UserRegistrationInformation myPersonalizerUserRegistrationInformation = userRegistrationInformationAccessor
162: .findUserRegistrationInformation(UserAndGroupConventions.MYPERSONALIZER_LOGIN_NAME);
163:
164: UserRegistrationInformationEditor myPersonalizerUserRegistrationInformationEditor = editorFactory
165: .createUserRegistrationInformationEditor(myPersonalizerUserRegistrationInformation
166: .getProperty());
167:
168: DesktopLayout myPersonalizerDesktopLayout = desktopLayoutAccessor
169: .findDesktopLayout(myPersonalizerUserRegistrationInformationEditor
170: .getDesktopLayoutPropertyIdentifier());
171:
172: DesktopLayoutEditor myPersonalizerDesktopLayoutEditor = editorFactory
173: .createDesktopLayoutEditor(myPersonalizerDesktopLayout
174: .getProperty());
175:
176: /*
177: * Now we create a property for the new user's user registration
178: * information by cloning the one for user "mypersonalizer".
179: * This cloned property will be a template for adding
180: * the new user's data. No valid DesktopLayoutIdentifier will
181: * be available by now, but we will build the user's DesktopLayout
182: * and assign its identifier before pushing the
183: * UserRegistrationInformation object into the repository.
184: */
185: Property userRegistrationInformationProperty = (Property) Cloner
186: .clone(myPersonalizerUserRegistrationInformation
187: .getProperty());
188:
189: PropertyUpdater propertyUpdater = propertyUpdaterRegistrySingleton
190: .getPropertyUpdater(propertyUpdaterName);
191:
192: propertyUpdater.update(userRegistrationInformationProperty,
193: signUpEvent);
194:
195: UserRegistrationInformationEditor userRegistrationInformationEditor = editorFactory
196: .createUserRegistrationInformationEditor(userRegistrationInformationProperty);
197:
198: String loginName = userRegistrationInformationEditor
199: .getLoginName();
200:
201: String password = userRegistrationInformationEditor
202: .getStoredPassword();
203:
204: userCredentials = new UserCredentials(loginName,
205: userCredentials.getUserGroupIdentifiers());
206:
207: String encryptedPassword = passwordManagerSingleton
208: .getPasswordToStore(password);
209:
210: userRegistrationInformationEditor
211: .setStoredPassword(encryptedPassword);
212:
213: /*
214: * Now we need to check if the user already exists, so as to
215: * avoid making any modification to the repository before a call
216: * to the UserRegistrationInformationAccessor would tell us
217: * if we really can add this user.
218: */
219: try {
220: userRegistrationInformationAccessor
221: .findUserRegistrationInformation(loginName);
222:
223: throw new DuplicateInstanceException(loginName,
224: "UserRegistrationInformation");
225:
226: } catch (InstanceNotFoundException e) {
227: }
228:
229: /*
230: * We create a "provisional" UserRegistrationInformation
231: * as we will need it for customization of the services that
232: * are going to be added to this user's workspaces
233: */
234: UserRegistrationInformation userRegistrationInformation = new UserRegistrationInformation(
235: loginName, userRegistrationInformationProperty);
236:
237: /*
238: * We create a fresh property for the DesktopLayout by cloning
239: * the one for "mypersonalizer".
240: */
241: Property desktopLayoutProperty = (Property) Cloner
242: .clone(myPersonalizerDesktopLayout.getProperty());
243:
244: DesktopLayoutEditor desktopLayoutEditor = editorFactory
245: .createDesktopLayoutEditor(desktopLayoutProperty);
246:
247: /*
248: * Now, we fill the new DesktopLayout with data, initializing it
249: * to have no workspaces (will be added later).
250: */
251: desktopLayoutEditor
252: .setDefaultWorkspaceLayoutIdentifier(null);
253: desktopLayoutEditor
254: .setWorkspaceLayoutIdentifiers(new ArrayList());
255: desktopLayoutEditor.updateTimeStamp();
256:
257: /* ...and push it into the repository */
258: DesktopLayout desktopLayout = desktopLayoutAccessor
259: .addDesktopLayout(desktopLayoutProperty);
260: desktopLayoutEditor
261: .setProperty(desktopLayout.getProperty());
262: Long desktopLayoutTimeStamp = desktopLayoutEditor
263: .getTimeStamp();
264:
265: /*
266: * No we can put the user registration information into the
267: * repository.
268: */
269: userRegistrationInformationEditor
270: .setDesktopLayoutPropertyIdentifier(desktopLayout
271: .getIdentifier());
272:
273: userRegistrationInformationEditor
274: .setRegistrationDate(Calendar.getInstance());
275:
276: userRegistrationInformationEditor
277: .setLastSignInDate(Calendar.getInstance());
278:
279: /*
280: * And the user registration information is pushed into the
281: * repository.
282: */
283: try {
284:
285: userRegistrationInformationAccessor
286: .addUserRegistrationInformation(userRegistrationInformation);
287:
288: } catch (DuplicateInstanceException e) {
289: throw new InternalErrorException(e);
290: }
291:
292: /*
293: * We add this user to the correspondent user groups.
294: */
295: Collection groupIdentifiers = userCredentials
296: .getUserGroupIdentifiers();
297: UserGroupAccessor userGroupAccessor = repositoryAccessorFactory
298: .createUserGroupAccessor();
299:
300: Iterator groupIdentifiersIter = groupIdentifiers.iterator();
301: while (groupIdentifiersIter.hasNext()) {
302:
303: Long currentGroupId = (Long) groupIdentifiersIter
304: .next();
305: userGroupAccessor.addUserToGroup(loginName,
306: currentGroupId);
307:
308: }
309:
310: /*
311: * We build a new suitable userCredentials object
312: */
313: userCredentials = new UserCredentials(loginName,
314: groupIdentifiers);
315:
316: /*
317: * Now we get the workspace layout identifiers in mypersonalizer's
318: * desktop so as to know if we have to create workspaces for the
319: * user or not.
320: */
321: List myPersonalizerWorkspaceLayoutIdentifiers = myPersonalizerDesktopLayoutEditor
322: .getWorkspaceLayoutIdentifiers();
323:
324: /*
325: * The objects needed for the SignInResult
326: */
327: List availableWorkspaces = new ArrayList();
328: WorkspaceLayout defaultWorkspaceLayout = null;
329: Collection defaultServiceButtonsStates = null;
330:
331: /*
332: * If there are no workspaces, we have nothing more to do.
333: */
334: if (!myPersonalizerWorkspaceLayoutIdentifiers.isEmpty()) {
335:
336: /*
337: * We get the identifier of the default workspace layout
338: * for mypersonalizer.
339: */
340: Long myPersonalizerDefaultWorkspaceLayoutIdentifier = myPersonalizerDesktopLayoutEditor
341: .getDefaultWorkspaceLayoutIdentifier();
342:
343: /*
344: * We get the list of the mypersonalizer workspace identifiers
345: * that are allowed for this user to be added.
346: */
347: List allowedWorkspaceLayoutIdentifiers = getAllowedWorkspaceLayoutIdentifiers(
348: userCredentials,
349: myPersonalizerWorkspaceLayoutIdentifiers);
350:
351: /*
352: * Now we iterate using the list of allowed workspace layout
353: * identifiers, and call the AddWorkspaceAction for each of
354: * them, creating all the needed objects about the user's
355: * desktop.
356: */
357: Iterator allowedWorkspaceLayoutIdentifiersIter = allowedWorkspaceLayoutIdentifiers
358: .iterator();
359: while (allowedWorkspaceLayoutIdentifiersIter.hasNext()) {
360:
361: Long currentWorkspaceLayoutIdentifier = (Long) allowedWorkspaceLayoutIdentifiersIter
362: .next();
363:
364: AddWorkspaceEvent addWorkspaceEvent = new AddWorkspaceEvent(
365: userCredentials, desktopLayout
366: .getIdentifier(),
367: currentWorkspaceLayoutIdentifier, null, // We don't specify a workspace name
368: desktopLayoutTimeStamp);
369:
370: /*
371: * Execution of the action to add a workspace.
372: */
373: AddWorkspaceResult addWorkspaceResult = null;
374: try {
375: addWorkspaceResult = (AddWorkspaceResult) actionProcessorSingleton
376: .execute(ADD_WORKSPACE_ACTION,
377: addWorkspaceEvent);
378: } catch (Exception e) {
379: /* This should never happen */
380: throw new InternalErrorException(e);
381: }
382:
383: /*
384: * If this is the workspace layout which will be the default
385: * one, we set the objects appropiately. The first is also
386: * set as default always to avoid problems as a result
387: * of the mypersonalizer's default one not being allowed.
388: */
389: if ((defaultWorkspaceLayout == null)
390: || (currentWorkspaceLayoutIdentifier
391: .equals(myPersonalizerDefaultWorkspaceLayoutIdentifier))) {
392: defaultWorkspaceLayout = addWorkspaceResult
393: .getNewWorkspaceLayout();
394: defaultServiceButtonsStates = addWorkspaceResult
395: .getNewServiceButtonsStates();
396:
397: }
398:
399: /*
400: * Now we add the new workspace to the available
401: * workspaces list.
402: */
403: WorkspaceLayout newWorkspaceLayout = addWorkspaceResult
404: .getNewWorkspaceLayout();
405: WorkspaceLayoutEditor newWorkspaceLayoutEditor = EditorFactory
406: .getInstance().createWorkspaceLayoutEditor(
407: newWorkspaceLayout.getProperty());
408: Map newEntry = new HashMap();
409: newEntry
410: .put("workspaceName",
411: newWorkspaceLayoutEditor
412: .getWorkspaceName());
413: newEntry.put("workspaceLayoutIdentifier",
414: newWorkspaceLayout.getIdentifier());
415: availableWorkspaces.add(newEntry);
416:
417: /*
418: * We get the desktop layout and the new time stamp.
419: */
420: desktopLayout = addWorkspaceResult
421: .getDesktopLayout();
422: desktopLayoutEditor.setProperty(desktopLayout
423: .getProperty());
424: desktopLayoutTimeStamp = desktopLayoutEditor
425: .getTimeStamp();
426:
427: }
428:
429: if (!allowedWorkspaceLayoutIdentifiers.isEmpty()) {
430: desktopLayoutEditor
431: .setDefaultWorkspaceLayoutIdentifier(defaultWorkspaceLayout
432: .getIdentifier());
433: desktopLayoutEditor.updateTimeStamp();
434: desktopLayoutAccessor
435: .updateDesktopLayout(desktopLayout);
436: desktopLayoutTimeStamp = desktopLayoutEditor
437: .getTimeStamp();
438:
439: }
440:
441: } // End of Workspace Layouts registration.
442:
443: /* We build the result and return */
444: SignInResult result = new SignInResult(loginName,
445: encryptedPassword, userCredentials
446: .getUserGroupIdentifiers(), desktopLayout,
447: availableWorkspaces, defaultWorkspaceLayout,
448: defaultServiceButtonsStates);
449:
450: return result;
451:
452: } catch (DuplicateInstanceException e) {
453:
454: throw e;
455:
456: } catch (InternalErrorException e) {
457:
458: throw e;
459:
460: } catch (Exception e) {
461:
462: throw new InternalErrorException(e);
463: }
464:
465: }
466:
467: private List getAllowedWorkspaceLayoutIdentifiers(
468: UserCredentials userCredentials,
469: List myPersonalizerWorkspaceLayoutIdentifiers)
470: throws InternalErrorException {
471:
472: RepositoryAccessorFactory repositoryAccessorFactory = RepositoryAccessorFactory
473: .getInstance();
474: WorkspaceLayoutAccessor workspaceLayoutAccessor = repositoryAccessorFactory
475: .createWorkspaceLayoutAccessor();
476: Map myPersonalizerWorkspaceLayouts = null;
477: try {
478: myPersonalizerWorkspaceLayouts = workspaceLayoutAccessor
479: .findWorkspaceLayouts(myPersonalizerWorkspaceLayoutIdentifiers);
480: } catch (InstanceNotFoundException e) {
481: throw new InternalErrorException(e);
482: }
483:
484: EditorFactory editorFactory = EditorFactory.getInstance();
485: PermissionCheckerSingleton permissionCheckerSingleton = PermissionCheckerSingleton
486: .getInstance();
487:
488: List result = new ArrayList();
489:
490: Iterator myPersonalizerWorkspaceLayoutsIter = myPersonalizerWorkspaceLayoutIdentifiers
491: .iterator();
492: while (myPersonalizerWorkspaceLayoutsIter.hasNext()) {
493:
494: Long currentIdentifier = (Long) myPersonalizerWorkspaceLayoutsIter
495: .next();
496: WorkspaceLayout currentWorkspaceLayout = (WorkspaceLayout) myPersonalizerWorkspaceLayouts
497: .get(currentIdentifier);
498: WorkspaceLayoutEditor currentWorkspaceLayoutEditor = editorFactory
499: .createWorkspaceLayoutEditor(currentWorkspaceLayout
500: .getProperty());
501: String currentWorkspaceType = currentWorkspaceLayoutEditor
502: .getWorkspaceType();
503:
504: if (permissionCheckerSingleton.isAllowedToAddWorkspace(
505: userCredentials, currentWorkspaceType)) {
506: result.add(currentIdentifier);
507: }
508:
509: }
510:
511: return result;
512:
513: }
514:
515: }
|