001    /**
002     * Copyright 2005-2014 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     */
016    package org.kuali.rice.kew.rule;
017    
018    import java.util.ArrayList;
019    import java.util.List;
020    
021    import org.kuali.rice.kew.api.identity.Id;
022    import org.kuali.rice.kew.api.rule.RuleExtension;
023    import org.kuali.rice.kew.engine.RouteContext;
024    import 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     */
058    public 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    }