/* * JBoss, Home of Professional Open Source * Copyright 2005, JBoss Inc., and individual contributors as indicated * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jbpm.identity.assignment; import java.util.Set; import net.conselldemallorca.helium.jbpm3.integracio.Jbpm3HeliumBridge; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jbpm.JbpmContext; import org.jbpm.graph.exe.ExecutionContext; import org.jbpm.graph.exe.Token; import org.jbpm.identity.Entity; import org.jbpm.identity.Group; import org.jbpm.identity.Membership; import org.jbpm.identity.User; import org.jbpm.identity.hibernate.IdentitySession; import org.jbpm.taskmgmt.def.AssignmentHandler; import org.jbpm.taskmgmt.exe.Assignable; import org.jbpm.taskmgmt.exe.SwimlaneInstance; /** * implements an expression language for assigning actors to tasks based * on this identity component. * * <pre>syntax : first-term --> next-term --> next-term --> ... --> next-term * * first-term ::= previous | * swimlane(swimlane-name) | * variable(variable-name) | * user(user-name) | * group(group-name) * * next-term ::= group(group-type) | * member(role-name) * </pre> */ public class ExpressionAssignmentHandler implements AssignmentHandler { private static final long serialVersionUID = 1L; protected String expression; protected ExecutionContext executionContext = null; protected ExpressionSession expressionSession = null; protected TermTokenizer tokenizer; protected Entity entity = null; protected Long entornId = null; protected HeliumExpressionAssignmentHandler heliumEah = null; @SuppressWarnings("unchecked") public void assign(Assignable assignable, ExecutionContext executionContext) { if (isHeliumAssignmentActive()) { getHeliumExpressionAssignmentHandler().setExpression(expression); getHeliumExpressionAssignmentHandler().setEntornId(entornId); getHeliumExpressionAssignmentHandler().assign(assignable, executionContext); } else { try { expressionSession = getExpressionSession(); if (expressionSession==null) { throw new NullPointerException("getIdentitySession returned null"); } this.tokenizer = new TermTokenizer(getExpression()); this.executionContext = executionContext; entity = resolveFirstTerm(tokenizer.nextTerm().trim()); while( tokenizer.hasMoreTerms() && (entity!=null) ) { entity = resolveNextTerm(tokenizer.nextTerm().trim()); } // if the expression did not resolve to an actor if (entity==null) { // throw an exception throw new RuntimeException("couldn't resolve assignment expression '"+getExpression()+"'"); // else if the expression evaluated to a user } else if (entity instanceof User) { // do direct assignment assignable.setActorId(entity.getName()); // else if the expression evaluated to a group } else if (entity instanceof Group) { // put the group in the pool Group g = (Group)entity; String[] actorIds = new String[g.getMemberships().size()]; int i = 0; for (Membership m: (Set<Membership>)g.getMemberships()) actorIds[i++] = m.getUser().getName(); assignable.setPooledActors(actorIds); } } catch (RuntimeException e) { throw new ExpressionAssignmentException("couldn't resolve assignment expression '"+getExpression()+"'", e); } } } public void setExpression(String expression) { this.expression = expression; } public void setEntornId(Long entornId) { this.entornId = entornId; } /** * serves as a hook for customizing the way the identity session is retrieved. * overload this method to reuse this expression assignment handler for your * user data store. */ @SuppressWarnings("deprecation") protected ExpressionSession getExpressionSession() { JbpmContext jbpmContext = JbpmContext.getCurrentJbpmContext(); if (jbpmContext==null) { throw new RuntimeException("no active JbpmContext for resolving assignment expression'"+getExpression()+"'"); } return new IdentitySession(jbpmContext.getSession()); } protected Entity resolveFirstTerm(String term) { Entity entity = null; log.debug("resolving first term '"+term+"'"); if (term.equalsIgnoreCase("previous")) { String userName = Jbpm3HeliumBridge.getInstanceService().getUsuariCodiActual(); entity = getUserByName(userName); } else if ( (term.startsWith("swimlane(")) && (term.endsWith(")")) ) { String swimlaneName = term.substring(9,term.length()-1).trim(); String userName = getSwimlaneActorId(swimlaneName); entity = getUserByName(userName); } else if ( (term.startsWith("variable(")) && (term.endsWith(")")) ) { String variableName = term.substring(9,term.length()-1).trim(); Object value = getVariable(variableName); if (value==null) { throw new ExpressionAssignmentException("variable '"+variableName+"' is null"); } else if (value instanceof String) { entity = expressionSession.getUserByName((String) value); if (entity == null) entity = expressionSession.getGroupByName((String) value); } else if (value instanceof Entity) { entity = (Entity) value; } } else if ( (term.startsWith("user(")) && (term.endsWith(")")) ) { String userName = term.substring(5,term.length()-1).trim(); entity = getUserByName(userName); } else if ( (term.startsWith("group(")) && (term.endsWith(")")) ) { String groupName = term.substring(6,term.length()-1).trim(); entity = getGroupByName(groupName); } else { throw new ExpressionAssignmentException("couldn't interpret first term in expression '"+getExpression()+"'"); } return entity; } protected Entity resolveNextTerm(String term) { log.debug("resolving next term '"+term+"'"); if ( (term.startsWith("group(")) && (term.endsWith(")")) ) { String groupType = term.substring(6,term.length()-1).trim(); User user = (User) entity; @SuppressWarnings("rawtypes") Set groups = user.getGroupsForGroupType(groupType); if (groups.size()==0) { throw new ExpressionAssignmentException("no groups for group-type '"+groupType+"'"); } entity = (Entity) groups.iterator().next(); } else if ( (term.startsWith("member(")) && (term.endsWith(")")) ) { String role = term.substring(7,term.length()-1).trim(); Group group = (Group) entity; entity = expressionSession.getUserByGroupAndRole(group.getName(), role); if (entity==null) { throw new ExpressionAssignmentException("no users in role '"+role+"'"); } } else { throw new ExpressionAssignmentException("couldn't interpret term '"+term+"' in expression '"+getExpression()+"'"); } return entity; } protected Object getVariable(String variableName) { Token token = executionContext.getToken(); return executionContext.getContextInstance().getVariable(variableName, token); } protected Entity getGroupByName(String groupName) { Group group = null; group = expressionSession.getGroupByName(groupName); if (group==null) { throw new ExpressionAssignmentException("group '"+groupName+"' couldn't be fetched from the user db"); } return group; } protected Entity getUserByName(String userName) { User user = null; user = expressionSession.getUserByName(userName); if (user==null) { throw new ExpressionAssignmentException("user '"+userName+"' couldn't be fetched from the user db"); } return user; } protected String getSwimlaneActorId(String swimlaneName) { SwimlaneInstance swimlaneInstance = executionContext .getTaskMgmtInstance() .getSwimlaneInstance(swimlaneName); if (swimlaneInstance==null) { throw new ExpressionAssignmentException("no swimlane instance '"+swimlaneName+"'"); } return swimlaneInstance.getActorId(); } private HeliumExpressionAssignmentHandler getHeliumExpressionAssignmentHandler() { if (heliumEah == null) heliumEah = new HeliumExpressionAssignmentHandler(); return heliumEah; } private String getExpression() { String expressio = expression; // lleva el tag <expression>...</expression> int indexInici = expressio.indexOf(">") + 1; int indexFi = expressio.lastIndexOf("<"); if (indexInici != -1 && indexFi != -1) return expressio.substring(indexInici, indexFi); return expressio; } private boolean isHeliumAssignmentActive() { String identitySource = Jbpm3HeliumBridge.getInstanceService().getHeliumProperty("app.jbpm.identity.source"); return "helium".equalsIgnoreCase(identitySource); } private static final Log log = LogFactory.getLog(ExpressionAssignmentHandler.class); }