001: /******************************************************************************
002: * JBoss, a division of Red Hat *
003: * Copyright 2006, Red Hat Middleware, LLC, and individual *
004: * contributors as indicated by the @authors tag. See the *
005: * copyright.txt in the distribution for a full listing of *
006: * individual contributors. *
007: * *
008: * This is free software; you can redistribute it and/or modify it *
009: * under the terms of the GNU Lesser General Public License as *
010: * published by the Free Software Foundation; either version 2.1 of *
011: * the License, or (at your option) any later version. *
012: * *
013: * This software is distributed in the hope that it will be useful, *
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of *
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
016: * Lesser General Public License for more details. *
017: * *
018: * You should have received a copy of the GNU Lesser General Public *
019: * License along with this software; if not, write to the Free *
020: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
021: * 02110-1301 USA, or see the FSF site: http://www.fsf.org. *
022: ******************************************************************************/package org.jboss.portal.core.identity.services.workflow.impl;
023:
024: import java.util.ArrayList;
025: import java.util.Iterator;
026: import java.util.List;
027: import java.util.Locale;
028: import java.util.Map;
029:
030: import org.jboss.logging.Logger;
031: import org.jboss.portal.common.io.IOTools;
032: import org.jboss.portal.core.identity.services.IdentityConstants;
033: import org.jboss.portal.core.identity.services.IdentityUserManagementService;
034: import org.jboss.portal.core.identity.services.metadata.CoreIdentityConfigurationException;
035: import org.jboss.portal.core.identity.services.metadata.IdentityUIConfiguration;
036: import org.jboss.portal.core.identity.services.metadata.IdentityUIConfigurationService;
037: import org.jboss.portal.core.identity.services.workflow.RegistrationService;
038: import org.jboss.portal.core.identity.services.workflow.UserContainer;
039: import org.jboss.portal.identity.User;
040: import org.jboss.portal.jems.as.JNDI;
041: import org.jboss.portal.jems.as.system.AbstractJBossService;
042: import org.jboss.portal.workflow.service.WorkflowService;
043: import org.jbpm.JbpmContext;
044: import org.jbpm.db.GraphSession;
045: import org.jbpm.graph.def.Node;
046: import org.jbpm.graph.def.ProcessDefinition;
047: import org.jbpm.graph.exe.ProcessInstance;
048: import org.jbpm.graph.exe.Token;
049:
050: /**
051: * @author <a href="mailto:emuckenh@redhat.com">Emanuel Muckenhuber</a>
052: * @version $Revision$
053: */
054: public class RegistrationServiceImpl extends AbstractJBossService
055: implements RegistrationService {
056:
057: /** The UserPortlet subscription mode */
058: private String subscriptionMode = null;
059:
060: /** The UserManagementPortlet subscription mode */
061: private String adminSubscriptionMode = null;
062:
063: /** The core-identity configuration service */
064: private IdentityUIConfigurationService identityUIConfigurationService;
065:
066: /** The core-identity user management service */
067: private IdentityUserManagementService identityUserManagementService;
068:
069: /** The jBPM workflow service */
070: private WorkflowService workflowService = null;
071:
072: /** The logger */
073: private static final Logger log = Logger
074: .getLogger(RegistrationServiceImpl.class);
075:
076: /** . */
077: private JNDI.Binding jndiBinding;
078:
079: /** . */
080: private String jndiName = null;
081:
082: public void startService() throws Exception {
083: super .startService();
084:
085: // Getting subscription modes
086: IdentityUIConfiguration cf = this .identityUIConfigurationService
087: .getConfiguration();
088: this .subscriptionMode = cf.getSubscriptionMode();
089: this .adminSubscriptionMode = cf.getAdminSubscriptionMode();
090:
091: if (this .jndiName != null) {
092: jndiBinding = new JNDI.Binding(jndiName, this );
093: jndiBinding.bind();
094: }
095: }
096:
097: public void stopService() throws Exception {
098: super .stopService();
099:
100: if (jndiBinding != null) {
101: jndiBinding.unbind();
102: jndiBinding = null;
103: }
104: }
105:
106: public WorkflowService getWorkflowService()
107: throws CoreIdentityConfigurationException {
108: if (this .workflowService == null) {
109: this .workflowService = identityUIConfigurationService
110: .getWorkflowService();
111: }
112: return this .workflowService;
113: }
114:
115: public void setWorkflowService(WorkflowService workflowService) {
116: this .workflowService = workflowService;
117: }
118:
119: public String getJNDIName() {
120: return this .jndiName;
121: }
122:
123: public void setJNDIName(String jndiName) {
124: this .jndiName = jndiName;
125: }
126:
127: public void setIdentityUIConfigurationService(
128: IdentityUIConfigurationService identityUIConfigurationService) {
129: this .identityUIConfigurationService = identityUIConfigurationService;
130: }
131:
132: public IdentityUIConfigurationService getIdentityUIConfigurationService() {
133: return identityUIConfigurationService;
134: }
135:
136: public IdentityUserManagementService getIdentityUserManagementService() {
137: return identityUserManagementService;
138: }
139:
140: public void setIdentityUserManagementService(
141: IdentityUserManagementService identityManagementService) {
142: this .identityUserManagementService = identityManagementService;
143: }
144:
145: public String registerUser(String url, String username,
146: String password, Map profileMap, List roles, Locale locale,
147: boolean adminFlag)
148: throws CoreIdentityConfigurationException {
149:
150: if (adminFlag) {
151: if (adminSubscriptionMode == null
152: || IdentityConstants.SUBSCRIPTION_MODE_AUTOMATIC
153: .equals(adminSubscriptionMode)) {
154: // Admin - automatic subscription
155: this .getIdentityUserManagementService().createUser(
156: username, password, profileMap, roles);
157: return IdentityConstants.REGISTRATION_REGISTERED;
158: } else {
159: // Admin - jBPM subscription
160: UserContainer user = new UserContainer(username,
161: password, profileMap, roles);
162: this .registerUserWorkflow(url, user, locale,
163: this .adminSubscriptionMode);
164: return IdentityConstants.REGISTRATION_PENDING;
165: }
166: } else {
167: if (subscriptionMode == null
168: || IdentityConstants.SUBSCRIPTION_MODE_AUTOMATIC
169: .equals(subscriptionMode)) {
170: // User - automatic subscription
171: this .getIdentityUserManagementService().createUser(
172: username, password, profileMap, roles);
173: return IdentityConstants.REGISTRATION_REGISTERED;
174: } else {
175: // User - jBPM subscription
176: UserContainer user = new UserContainer(username,
177: password, profileMap, roles);
178: this .registerUserWorkflow(url, user, locale,
179: this .subscriptionMode);
180: return IdentityConstants.REGISTRATION_PENDING;
181: }
182: }
183: }
184:
185: private void registerUserWorkflow(String url, UserContainer user,
186: Locale locale, String processName)
187: throws CoreIdentityConfigurationException {
188: JbpmContext jbpmContext = null;
189: ProcessInstance processInstance = null;
190: boolean success = false;
191:
192: try {
193: jbpmContext = this .getWorkflowService()
194: .getJbpmConfiguration().createJbpmContext();
195: processInstance = jbpmContext
196: .newProcessInstance(processName);
197: Token token = processInstance.getRootToken();
198:
199: // Setting required attributes for the workflow
200: processInstance.getContextInstance().setVariable(
201: IdentityConstants.PORTAL_URL, url);
202: processInstance.getContextInstance().setVariable(
203: IdentityConstants.VARIABLE_USER, user);
204: processInstance.getContextInstance()
205: .setVariable(
206: IdentityConstants.VARIABLE_EMAIL,
207: user.getProfileMap().get(
208: User.INFO_USER_EMAIL_REAL));
209: processInstance.getContextInstance().setVariable(
210: IdentityConstants.VARIABLE_LOCALE, locale);
211: processInstance.getContextInstance().setVariable(
212: IdentityConstants.ACTION,
213: IdentityConstants.ACTION_REGISTER_USER);
214:
215: token.signal();
216: success = true;
217: } finally {
218: if (processInstance != null && success) {
219: jbpmContext.save(processInstance);
220: }
221: IOTools.safeClose(jbpmContext);
222: }
223: }
224:
225: public String approve(String id, boolean approve)
226: throws CoreIdentityConfigurationException {
227: // return registered if workflow is disabled
228: if (!this .identityUIConfigurationService.getConfiguration()
229: .enableWorkflow()) {
230: return IdentityConstants.REGISTRATION_REGISTERED;
231: }
232:
233: JbpmContext jbpmContext = null;
234: try {
235: long processId = Long.valueOf(id).longValue();
236: jbpmContext = this .getWorkflowService()
237: .getJbpmConfiguration().createJbpmContext();
238: ProcessInstance processInstance = jbpmContext
239: .getProcessInstance(processId);
240:
241: if (processInstance != null) {
242: Token token = processInstance.getRootToken();
243: if (token.getNode().getName().equals(
244: IdentityConstants.JBPM_NODE_APPROVAL)) {
245: if (approve) {
246: token
247: .signal(IdentityConstants.JBPM_TRANSITION_APPROVED);
248: } else {
249: token
250: .signal(IdentityConstants.JBPM_TRANSITION_REJECTED);
251: }
252: }
253: }
254: } finally {
255: IOTools.safeClose(jbpmContext);
256: }
257: return IdentityConstants.REGISTRATION_PENDING;
258: }
259:
260: public int getPendingCount()
261: throws CoreIdentityConfigurationException {
262: int count = 0;
263: JbpmContext jbpmContext = null;
264: try {
265: List userProcessInstances = this .getProcessInstances(
266: jbpmContext, this .subscriptionMode);
267: if (userProcessInstances != null
268: && userProcessInstances.size() > 0) {
269: Iterator i = userProcessInstances.iterator();
270: while (i.hasNext()) {
271: ProcessInstance instance = (ProcessInstance) i
272: .next();
273: Node node = instance.getRootToken().getNode();
274: if (IdentityConstants.JBPM_NODE_APPROVAL
275: .equals(node.getName()))
276: count = !instance.hasEnded() ? count + 1
277: : count;
278: }
279: }
280: if (!this .adminSubscriptionMode
281: .equals(this .subscriptionMode)
282: && !this .adminSubscriptionMode
283: .equals(IdentityConstants.SUBSCRIPTION_MODE_AUTOMATIC)) {
284: List adminProcessInstances = this .getProcessInstances(
285: jbpmContext, this .adminSubscriptionMode);
286: if (adminProcessInstances != null
287: && adminProcessInstances.size() > 0) {
288: Iterator i = adminProcessInstances.iterator();
289: while (i.hasNext()) {
290: ProcessInstance instance = (ProcessInstance) i
291: .next();
292: Node node = instance.getRootToken().getNode();
293: if (IdentityConstants.JBPM_NODE_APPROVAL
294: .equals(node.getName()))
295: count = !instance.hasEnded() ? count + 1
296: : count;
297: }
298: }
299: }
300: } finally {
301: IOTools.safeClose(jbpmContext);
302: }
303: return count;
304: }
305:
306: public List getPendingUsers(String nodeName)
307: throws CoreIdentityConfigurationException {
308: List queue = new ArrayList();
309: JbpmContext jbpmContext = null;
310: try {
311: List userProcessInstances = this .getProcessInstances(
312: jbpmContext, this .subscriptionMode);
313: if (userProcessInstances != null
314: && userProcessInstances.size() > 0) {
315: queue.addAll(this .getPendingUser(userProcessInstances,
316: nodeName));
317: }
318:
319: if (!this .adminSubscriptionMode
320: .equals(this .subscriptionMode)
321: && !this .adminSubscriptionMode
322: .equals(IdentityConstants.SUBSCRIPTION_MODE_AUTOMATIC)) {
323: List adminProcessInstances = this .getProcessInstances(
324: jbpmContext, this .adminSubscriptionMode);
325: if (adminProcessInstances != null
326: && adminProcessInstances.size() > 0) {
327: queue.addAll(this .getPendingUser(
328: adminProcessInstances, nodeName));
329: }
330: }
331: } finally {
332: IOTools.safeClose(jbpmContext);
333: }
334: return queue;
335: }
336:
337: private List getPendingUser(List processInstances, String nodeName) {
338: List queue = new ArrayList();
339: if (processInstances != null) {
340: Iterator i = processInstances.iterator();
341: while (i.hasNext()) {
342: ProcessInstance instance = (ProcessInstance) i.next();
343: if (!instance.hasEnded()) {
344: Node node = instance.getRootToken().getNode();
345: Object obj = instance.getContextInstance()
346: .getVariable(
347: IdentityConstants.VARIABLE_USER);
348:
349: // Filter by node
350: if (nodeName != null
351: && nodeName.equals(node.getName())) {
352: if (obj instanceof UserContainer) {
353: // Filling pending user List
354: UserContainer user = (UserContainer) obj;
355: user.setProcessId(String.valueOf(instance
356: .getId()));
357: user.setCurrentNode(node.getName());
358: queue.add(user);
359: }
360: } else if (nodeName == null) {
361: if (obj instanceof UserContainer) {
362: // Filling pending user List
363: UserContainer user = (UserContainer) obj;
364: user.setProcessId(String.valueOf(instance
365: .getId()));
366: user.setCurrentNode(node.getName());
367: queue.add(user);
368: }
369: }
370: }
371: }
372: }
373: return queue;
374: }
375:
376: public boolean checkUsername(String username)
377: throws CoreIdentityConfigurationException {
378: JbpmContext jbpmContext = null;
379: try {
380: List userProcessInstances = this .getProcessInstances(
381: jbpmContext, this .subscriptionMode);
382: if (userProcessInstances != null
383: && userProcessInstances.size() > 0) {
384: if (this .checkUsername(userProcessInstances, username))
385: return true;
386: }
387:
388: if (!this .adminSubscriptionMode
389: .equals(this .subscriptionMode)
390: && !this .adminSubscriptionMode
391: .equals(IdentityConstants.SUBSCRIPTION_MODE_AUTOMATIC)) {
392: List adminProcessInstances = this .getProcessInstances(
393: jbpmContext, this .adminSubscriptionMode);
394: if (adminProcessInstances != null
395: && adminProcessInstances.size() > 0) {
396: if (this .checkUsername(adminProcessInstances,
397: username))
398: return true;
399: }
400: }
401: } finally {
402: IOTools.safeClose(jbpmContext);
403: }
404: return false;
405: }
406:
407: private boolean checkUsername(List processInstances, String username) {
408: boolean usernameTaken = false;
409: if (processInstances != null) {
410: Iterator i = processInstances.iterator();
411: while (i.hasNext()) {
412: ProcessInstance instance = (ProcessInstance) i.next();
413: if (!instance.hasEnded()) {
414: Object obj = instance.getContextInstance()
415: .getVariable(
416: IdentityConstants.VARIABLE_USER);
417: if (obj instanceof UserContainer) {
418: UserContainer user = (UserContainer) obj;
419: if (username != null
420: && username.equals(user.getUsername())) {
421: usernameTaken = true;
422: }
423: }
424: }
425: }
426: }
427: return usernameTaken;
428: }
429:
430: private List getProcessInstances(JbpmContext jbpmContext,
431: String processName)
432: throws CoreIdentityConfigurationException {
433: List processInstances = new ArrayList();
434: if (!IdentityConstants.SUBSCRIPTION_MODE_AUTOMATIC
435: .equals(processName)) {
436: if (jbpmContext == null) {
437: jbpmContext = this .getWorkflowService()
438: .getJbpmConfiguration().createJbpmContext();
439: }
440: GraphSession graphSession = jbpmContext.getGraphSession();
441: ProcessDefinition processDefinition = graphSession
442: .findLatestProcessDefinition(processName);
443: if (processDefinition != null) {
444: processInstances = graphSession
445: .findProcessInstances(processDefinition.getId());
446: } else {
447: throw new CoreIdentityConfigurationException(
448: "Could not find process definition for process name: "
449: + processName);
450: }
451: }
452: return processInstances;
453: }
454:
455: }
|