001/**
002 * Copyright 2005-2016 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.kew.rule;
017
018import java.util.ArrayList;
019import java.util.List;
020
021import org.kuali.rice.kew.api.identity.Id;
022import org.kuali.rice.kew.api.rule.RuleExtension;
023import org.kuali.rice.kew.engine.RouteContext;
024import org.kuali.rice.kew.routeheader.DocumentContent;
025
026
027/**
028 * Generic base class that implements common functionality to simplify implementing
029 * a RoleAttribute.  This includes a standard qualified role name String format and simplified
030 * template methods, as well as a generic attribute content model.
031 * 
032 * <p>Control flow:</p>
033 * 
034 * <ol>
035 *   <li>{@link #getQualifiedRoleNames(String, DocumentContent)}
036 *     <ol>
037 *       <li>{@link #generateQualifiedRoleNames(String, DocumentContent)}
038 *         <ol>
039 *           <li>{@link #getRoleNameQualifiers(String, DocumentContent)}</li>
040 *         </ol>
041 *       </li>
042 *     </ol>
043 *   </li>
044 *   <li>{@link #resolveQualifiedRole(RouteContext, String, String)}
045 *     <ol>
046 *       <li>{@link #resolveQualifiedRole(RouteContext, QualifiedRoleName)}
047 *         <ol>
048 *           <li>{@link #resolveRecipients(RouteContext, QualifiedRoleName)}</li>
049 *           <li>{@link #getLabelForQualifiedRoleName(QualifiedRoleName)}</li>
050 *         </ol>
051 *       </li>
052 *     </ol>
053 *   </li>
054 * </ol> 
055 *     
056 * @author Kuali Rice Team (rice.collab@kuali.org)
057 */
058public abstract class GenericRoleAttribute extends GenericWorkflowAttribute implements RoleAttribute {
059    public GenericRoleAttribute() {
060        super(null);
061    }
062
063    public GenericRoleAttribute(String uniqueName) {
064        super(uniqueName);
065    }
066
067    public boolean isMatch(DocumentContent docContent, List<RuleExtension> ruleExtensions) {
068        // FIXME: ok, this MUST return true, as it IS evaluated (don't know why)
069        // maybe investigate only calling isMatch on rule attributes as it doesn't seem that
070        // matching is relevant for role attributes...is it?
071        // throw new UnsupportedOperationException("Role attributes do not implement isMatch");
072        return true;
073    }
074
075    public List<String> getQualifiedRoleNames(String roleName, DocumentContent documentContent) {
076        List<QualifiedRoleName> qualifiedRoleNames = generateQualifiedRoleNames(roleName, documentContent);
077        if (qualifiedRoleNames == null) {
078            return null;
079        }
080        List<String> q = new ArrayList<String>(qualifiedRoleNames.size());
081        for (QualifiedRoleName qrn: qualifiedRoleNames) {
082            q.add(qrn.encode());
083        }
084        return q;
085    }
086
087    /**
088     * Template method responsible for producing a list of QualifiedRoleName objects.  Default implementation
089     * calls {@link #getRoleNameQualifiers(String, DocumentContent)}
090     */
091    protected List<QualifiedRoleName> generateQualifiedRoleNames(String roleName, DocumentContent documentContent) {
092        List<String> qualifiers = getRoleNameQualifiers(roleName, documentContent);
093        if (qualifiers == null) {
094            qualifiers = new ArrayList<String>(0);
095        }
096        List<QualifiedRoleName> qualifiedRoleNames = new ArrayList<QualifiedRoleName>(qualifiers.size());
097        for (String qualifier: qualifiers) {
098            qualifiedRoleNames.add(new QualifiedRoleName(roleName, qualifier));
099        }
100        return qualifiedRoleNames;
101    }
102
103    /**
104     * Template method responsible for producing qualifiers for a role name
105     */
106    protected List<String> getRoleNameQualifiers(String roleName, DocumentContent documentContent) {
107        return null;
108    }
109
110    public ResolvedQualifiedRole resolveQualifiedRole(RouteContext routeContext, String roleName, String qualifiedRoleName) {
111        QualifiedRoleName qrn = QualifiedRoleName.parse(qualifiedRoleName);
112        return resolveQualifiedRole(routeContext, qrn);
113    }
114
115    /**
116     * Template method that delegates to {@link #resolveRecipients(RouteContext, QualifiedRoleName)} and
117     * {@link #getLabelForQualifiedRoleName(QualifiedRoleName)
118     */
119    protected ResolvedQualifiedRole resolveQualifiedRole(RouteContext routeContext, QualifiedRoleName qualifiedRoleName) {
120        List<Id> recipients = resolveRecipients(routeContext, qualifiedRoleName);
121        ResolvedQualifiedRole rqr = new ResolvedQualifiedRole(getLabelForQualifiedRoleName(qualifiedRoleName),
122                                                              recipients
123                                                              ); // default to no annotation...
124        return rqr;
125    }
126
127    protected String getLabelForQualifiedRoleName(QualifiedRoleName qualifiedRoleName) {
128        // do what everybody else does and just use the base role name
129        return qualifiedRoleName.getBaseRoleName();
130    }
131
132    /**
133     * Template method for subclasses to implement
134     */
135    protected List<Id> resolveRecipients(RouteContext routeContext, QualifiedRoleName qualifiedRoleName) {
136        return null;
137    }
138}