001/**
002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003 *
004 * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved
005 *
006 * The contents of this file are subject to the terms
007 * of the Common Development and Distribution License
008 * (the License). You may not use this file except in
009 * compliance with the License.
010 *
011 * You can obtain a copy of the License at
012 * https://opensso.dev.java.net/public/CDDLv1.0.html or
013 * opensso/legal/CDDLv1.0.txt
014 * See the License for the specific language governing
015 * permission and limitations under the License.
016 *
017 * When distributing Covered Code, include this CDDL
018 * Header Notice in each file and include the License file
019 * at opensso/legal/CDDLv1.0.txt.
020 * If applicable, add the following below the CDDL Header,
021 * with the fields enclosed by brackets [] replaced by
022 * your own identifying information:
023 * "Portions Copyrighted [year] [name of copyright owner]"
024 *
025 * $Id: Rule.java,v 1.8 2009/11/13 23:52:20 asyhuang Exp $
026 *
027 * Portions Copyrighted 2011-2016 ForgeRock AS.
028 */
029package com.sun.identity.policy;
030
031import com.iplanet.sso.SSOException;
032import com.sun.identity.shared.xml.XMLUtils;
033import org.w3c.dom.Node;
034
035import java.util.HashSet;
036import java.util.Map;
037import java.util.Set;
038import java.util.HashMap;
039import java.util.Iterator;
040
041
042/**
043 * The class <code>Rule</code> provides interfaces to manage
044 * a rule that can be added to a policy.
045 * A rule constains the rule name, service type,
046 * a resource and a map containing action names and action values.
047 *
048 * @supported.api
049 * @deprecated since 12.0.0
050 */
051@Deprecated
052public class Rule extends Object implements Cloneable {
053
054    /** Empty resource name. */
055    public static final String EMPTY_RESOURCE_NAME = "";
056
057    // Name of the rule
058    private String ruleName;
059
060    // Service type
061    private String serviceTypeName;
062    private ServiceType serviceType;
063
064    // Resource for which the rule applies.
065    Set<String> resourceNames = new HashSet<String>();
066    private String applicationName;
067
068    // Actions allowed on the resource
069    private Map actions;
070
071    /**
072     * Contruct a <code>Rule</code>.
073     */
074    protected Rule() {
075        // do nothing
076    }
077
078    /**
079     * Constructor to create a rule object with the
080     * service name, resource name and actions. The actions
081     * provided as a <code>Map</code> must have the action
082     * name as key and a <code>Set</code> of <code>String</code>s
083     * as its value. The action names and action values must
084     * conform to the schema specified for the service.
085     * Otherwise, <code>InvalidNameException
086     * </code> is thrown. The parameters <code>ruleName</code>
087     * and <code>resourceName</code> can be <code>null</code>.
088     *
089     * @param serviceName name of the service type as defined by
090     * the service schema
091     * @param resourceName name of the resource for the service type
092     * @param actions map of action and action values for the resource
093     *
094     * @exception NameNotFoundException the service name provided does
095     * not exist
096     * @exception InvalidNameException the resource name, action name,
097     * or values is not valid
098     * @supported.api
099     */
100    public Rule(String serviceName, String resourceName, Map actions) throws
101            NameNotFoundException, InvalidNameException {
102        this(null, serviceName, resourceName, actions);
103    }
104
105    /**
106     * Constructor to create a rule object with the
107     * service name and actions. This is useful for
108     * services (and possibly action names) that do not have
109     * resource names. The actions
110     * provided as a <code>Map</code> must have the action
111     * name as it key and a <code>Set</code> of <code>String</code>s
112     * as its value. The action names and action values must
113     * conform to the schema specified for the service.
114     * Otherwise, <code>InvalidNameException
115     * </code> is thrown. The parameters <code>ruleName</code>
116     * and <code>resourceName</code> can be <code>null</code>.
117     *
118     * @param serviceName name of the service type as defined by
119     * the service schema
120     * @param actions map of action and action values for the resource
121     *
122     * @exception NameNotFoundException the service name provided does
123     * not exist
124     * @exception InvalidNameException the resource name, action name,
125     * or values is not valid
126     * @supported.api
127     */
128    public Rule(String serviceName, Map actions) throws
129            NameNotFoundException, InvalidNameException {
130        this(null, serviceName, null, actions);
131    }
132
133    /**
134     * Constructor to create a rule object with rule name,
135     * service name, resource name and actions. The actions
136     * provided as a <code>Map</code> must have the action
137     * name as it key and a <code>Set</code> of <code>String</code>s
138     * as its value. The action names and action values must
139     * conform to the service schema.
140     * Otherwise, <code>InvalidNameException
141     * </code> is thrown. The parameters <code>ruleName</code>
142     * and <code>resourceName</code> can be <code>null</code>.
143     *
144     * @param ruleName name of the rule
145     * @param serviceName name of the service type as defined by
146     *        the service schema
147     * @param resourceName name of the resource for the service type
148     * @param actions map of action and action values for the resource
149     *
150     * @exception NameNotFoundException the service name provided does
151     * not exist
152     * @exception InvalidNameException the resource name, action name,
153     * or values is not valid
154     * @supported.api
155     */
156    public Rule(String ruleName, String serviceName,
157            String resourceName, Map actions) throws
158            NameNotFoundException, InvalidNameException {
159        PolicyManager.initAdminSubject();
160        // Rule and resource name can be null
161        this.ruleName = (ruleName != null) ? ruleName : ("rule" + ServiceTypeManager.generateRandomName());
162        this.resourceNames = new HashSet<String>();
163        this.serviceTypeName = serviceName;
164
165        if ((resourceName == null) || (resourceName.length() == 0)) {
166            resourceNames.add(EMPTY_RESOURCE_NAME);
167        } else {
168            resourceName = resourceName.trim();
169            resourceNames.add(resourceName);
170        }
171
172        if (actions != null) {
173            this.actions = new HashMap(actions);
174        } else {
175            this.actions = new HashMap();
176        }
177    }
178
179    /**
180     * Sets application Name.
181     *
182     * @param applicationName Application name.
183     */
184    public void setApplicationName(String applicationName) {
185        this.applicationName = applicationName;
186    }
187
188    /**
189     * Returns application name.
190     *
191     * @return application name.
192     */
193    public String getApplicationName() {
194        return (applicationName == null) ? serviceTypeName : applicationName;
195    }
196
197
198    /**
199     * Constructor to create a <code>Rule</code> object from a XML Node.
200     * @param ruleNode XML node representation of <code>Rule</code>
201     * @throws InvalidFormatException on invalid xml
202     * @throws InvalidNameException thrown by called routines
203     * @throws NameNotFoundException thrown by called routines
204
205     */
206    protected Rule(Node ruleNode) throws InvalidFormatException,
207            InvalidNameException, NameNotFoundException {
208        // Make sure the node name is rule
209        if (!ruleNode.getNodeName().equalsIgnoreCase(
210                PolicyManager.POLICY_RULE_NODE)) {
211            if (PolicyManager.debug.warningEnabled()) {
212                PolicyManager.debug.warning(
213                        "invalid rule xml blob given to constructor");
214            }
215            throw (new InvalidFormatException(ResBundleUtils.rbName,
216                    "invalid_xml_rule_node", null, "", PolicyException.RULE));
217        }
218
219        PolicyManager.initAdminSubject();
220        // Get rule name, can be null
221        if ((ruleName = XMLUtils.getNodeAttributeValue(ruleNode,
222                PolicyManager.NAME_ATTRIBUTE)) == null) {
223            ruleName = "rule" + ServiceTypeManager.generateRandomName();
224        }
225
226        // Get the service type name, cannot be null
227        Node serviceNode = XMLUtils.getChildNode(ruleNode,
228                PolicyManager.POLICY_RULE_SERVICE_NODE);
229        if ((serviceNode == null) || ((serviceTypeName = XMLUtils.getNodeAttributeValue(serviceNode,
230                                                                        PolicyManager.NAME_ATTRIBUTE)) == null)) {
231            if (PolicyManager.debug.warningEnabled()) {
232                PolicyManager.debug.warning(
233                        "invalid service name in rule xml blob in constructor");
234            }
235            String[] objs = {((serviceTypeName == null) ? "null" : serviceTypeName)};
236            throw (new InvalidFormatException(ResBundleUtils.rbName,
237                    "invalid_xml_rule_service_name", objs,
238                    ruleName, PolicyException.RULE));
239        }
240        checkAndSetServiceType(serviceTypeName);
241
242        Node applicationNameNode = XMLUtils.getChildNode(ruleNode,
243            PolicyManager.POLICY_RULE_APPLICATION_NAME_NODE);
244        if (applicationNameNode != null) {
245            applicationName = XMLUtils.getNodeAttributeValue(
246                applicationNameNode, PolicyManager.NAME_ATTRIBUTE);
247        }
248
249        resourceNames = new HashSet<String>();
250        resourceNames.addAll(getResources(ruleNode,
251            PolicyManager.POLICY_RULE_RESOURCE_NODE));
252
253        Set<String> excludeResources = getResources(ruleNode,
254            PolicyManager.POLICY_RULE_EXCLUDED_RESOURCE_NODE);
255
256        // Get the actions and action values, cannot be null
257        Set actionNodes = XMLUtils.getChildNodes(ruleNode,
258                PolicyManager.ATTR_VALUE_PAIR_NODE);
259        actions = new HashMap();
260        if (actionNodes != null) {
261            Iterator items = actionNodes.iterator();
262            while (items.hasNext()) {
263                // Get action name & values
264                String actionName = null;
265                Set actionValues = null;
266                Node node = (Node) items.next();
267                Node attrNode = XMLUtils.getChildNode(node, PolicyManager.ATTR_NODE);
268                if ((attrNode == null) || ((actionName = XMLUtils.getNodeAttributeValue(attrNode,
269                        PolicyManager.NAME_ATTRIBUTE)) == null) || ((actionValues =
270                        XMLUtils.getAttributeValuePair(node)) == null)) {
271                    String[] objs = {((actionName == null) ? "null" : actionName)};
272                    throw (new InvalidFormatException(
273                            ResBundleUtils.rbName,
274                            "invalid_xml_rule_action_name", objs,
275                            ruleName, PolicyException.RULE));
276                }
277                actions.put(actionName, actionValues);
278
279            }
280            // Validate the action values
281            //serviceType.validateActionValues(actions);
282        }
283    }
284
285    private Set<String> getResources(
286        Node ruleNode,
287        String childNodeName
288    ) throws InvalidNameException {
289        PolicyManager.initAdminSubject();
290        Set<String> container = null;
291        Set children = XMLUtils.getChildNodes(ruleNode, childNodeName);
292
293        if ((children != null) && !children.isEmpty()) {
294            container = new HashSet<String>();
295            for (Iterator i = children.iterator(); i.hasNext();) {
296                Node resourceNode = (Node) i.next();
297                String resourceName = XMLUtils.getNodeAttributeValue(
298                    resourceNode, PolicyManager.NAME_ATTRIBUTE);
299                if (resourceName != null) {
300                    resourceName = resourceName.trim();
301                    container.add(resourceName);
302                }
303            }
304        }
305        return container;
306    }
307
308    /**
309     * Sets the service type name of this object.
310     * @param serviceTypeName service type name for this object
311     * @exception NameNotFoundException the service type name provided does
312     * not exist
313     */
314    private void checkAndSetServiceType(String serviceTypeName)
315            throws NameNotFoundException {
316        // Check the service type name
317        PolicyManager.initAdminSubject();
318        ServiceTypeManager stm = null;
319        try {
320            stm = ServiceTypeManager.getServiceTypeManager();
321            serviceType = stm.getServiceType(serviceTypeName);
322        } catch (SSOException ssoe) {
323            PolicyManager.debug.error("Unable to get admin SSO token" + ssoe);
324            throw (new NameNotFoundException(ssoe,
325                    serviceTypeName, PolicyException.SERVICE));
326        }
327    }
328
329    /**
330     * Returns the name assigned to the rule. It could be <code>null</code>
331     * if it was not constructed with a name.
332     *
333     * @return rule name
334     * @supported.api
335     */
336    public String getName() {
337        return (ruleName);
338    }
339
340    /**
341     * Sets the name for the rule. If a name has already been
342     * assigned, it will be replaced with the given name.
343     *
344     * @param ruleName rule name.
345     * @throws InvalidNameException if rule name is invalid.
346     * @supported.api
347     */
348    public void setName(String ruleName) throws InvalidNameException {
349        if (ruleName != null) {
350            this.ruleName = ruleName;
351        } else {
352            this.ruleName = "rule" + ServiceTypeManager.generateRandomName();
353        }
354    }
355
356    /**
357     * Returns the service name for which the rule has been created.
358     * The service name of the rule cannot be changed once the rule is
359     * created.
360     *
361     * @return service name
362     * @supported.api
363     */
364    public String getServiceTypeName() {
365        return (serviceTypeName);
366    }
367
368    /**
369     * Returns the resource name for which the rule has been created.
370     * If the service does not support resource names, the method
371     * will return <code>null</code>. The resource name of
372     * the rule cannot be changed once the rule is created.
373     *
374     * @return resource name
375     * @supported.api
376     */
377    public String getResourceName() {
378        return ((resourceNames == null) || resourceNames.isEmpty())
379                ? EMPTY_RESOURCE_NAME : resourceNames.iterator().next();
380    }
381
382    /**
383     * Returns the resource names for which the rule has been created.
384     * If the service does not support resource names, the method
385     * will return <code>null</code>. The resource name of
386     * the rule cannot be changed once the rule is created.
387     *
388     * @return resource name
389     * @supported.api
390     */
391    public Set<String> getResourceNames() {
392        return resourceNames;
393    }
394
395    /**
396     * Sets the resource names for which the rule has been created.
397     * If the service does not support resource names, the method
398     * will return <code>null</code>. The resource name of
399     * the rule cannot be changed once the rule is created.
400     *
401     * @param resourceNames resource name
402     * @supported.api
403     */
404    public void setResourceNames(Set<String> resourceNames) {
405        this.resourceNames = new HashSet<String>();
406        if (resourceNames != null) {
407            this.resourceNames.addAll(resourceNames);
408        }
409    }
410
411    /**
412     * Returns the action names that have been set for the rule.
413     * The action names returned could be the same as the service's
414     * action names or a subset of it.
415     *
416     * @return action names defined in this rule for the service
417     * @supported.api
418     */
419    public Set getActionNames() {
420        return (new HashSet(actions.keySet()));
421    }
422
423    /**
424     * Returns a set of action values that have been set for the
425     * specified action name.
426     *
427     * @param actionName action name for which to compute values.
428     * @return action names defined in this rule for the service
429     * @throws NameNotFoundException if actions name is not
430     *         found in the rule
431     * @supported.api
432     */
433    public Set getActionValues(String actionName)
434            throws NameNotFoundException {
435        Set<String> answer = (Set<String>) actions.get(actionName);
436        if (answer != null) {
437            Set clone = new HashSet();
438            clone.addAll(answer);
439            return clone;
440        }
441        return (answer);
442    }
443
444    /**
445     * Returns a <code>Map</code> of all action names and their
446     * corresponding action values that have been set in the rule.
447     * The "key" of the <code>Map</code> will be the action name
448     * as a string, and its "value" will be a <code>Set</code>
449     * which contains the action values as strings.
450     *
451     * @return all action names and corresponding action values
452     * @supported.api
453     */
454    public Map getActionValues() {
455        return (new HashMap(actions));
456    }
457
458    /**
459     * Sets the action names and their corresponding actions values
460     * (or permissions) for the resource or the service.
461     *
462     * @param actionValues action names and their corresponding values
463     * @throws InvalidNameException if action name is invalid.
464     * @supported.api
465     */
466    public void setActionValues(Map actionValues)
467            throws InvalidNameException {
468        serviceType.validateActionValues(actionValues);
469        actions = new HashMap(actionValues);
470    }
471
472    /**
473     * Checks if two rule objects are identical. Two rules are
474     * identical only if the service name, resource name,
475     * action name and values match.
476     *
477     * @param obj object against which this rule object
478     * will be checked for equality
479     *
480     * @return <code>true</code> if the service type, resource, actions
481     * and action values match, <code>false</code> otherwise.
482     */
483    @Override
484    public boolean equals(Object obj) {
485        boolean matched = true;
486        if (obj == null || !(obj instanceof Rule)) {
487            return false;
488        }
489        Rule other = (Rule) obj;
490
491        if (applicationName == null) {
492            if (other.applicationName != null) {
493                return false;
494            }
495        } else if (!applicationName.equals(other.applicationName)) {
496            return false;
497        }
498
499        if (resourceNames == null) {
500            if (other.resourceNames != null) {
501                return false;
502            }
503        } else {
504            if (!resourceNames.equals(other.resourceNames)) {
505                return false;
506            }
507        }
508
509        if (!actions.equals(other.actions)) {
510            return false;
511        }
512        return matched;
513    }
514
515    /**
516     * This added by when CheckStyle noticed there was an implementation of
517     * equals without an implementation of hashCode - usually a recipe for
518     * disaster.
519     *
520     * @return the hashCode for this object
521     */
522    @Override
523    public int hashCode() {
524        int result = super.hashCode();
525        if (applicationName != null) {
526            result = 37 * result + applicationName.hashCode();
527        }
528        if (resourceNames != null) {
529            result = 37 * result + resourceNames.hashCode();
530        }
531        if (actions != null) {
532            result = 37 * result + actions.hashCode();
533        }
534        return result;
535    }
536
537    /**
538     * Compares the given service and resource names with the
539     * service and resource name specified in this rule.
540     * The method returns a <code>ResourceMatch</code> object which
541     * specifies if the resources match exactly, do not match, or one
542     * of them is a subordinate resource of the other. If the
543     * service name does not match, the method returns <code>
544     * NO_MATCH</code>.
545     *
546     * @param serviceName name of the service
547     * @param resourceName name of the resource
548     *
549     * @return returns <code>ResourceMatch</code> that
550     * specifies if the service name and resource name are exact match, or
551     * otherwise.
552     */
553    public ResourceMatch isResourceMatch(
554            String serviceName,
555            String resourceName) {
556
557        ResourceMatch rm = null;
558        if (!serviceName.equalsIgnoreCase(serviceTypeName)) {
559            rm = ResourceMatch.NO_MATCH;
560        } else {
561            //rm = serviceType.compare(this.resourceName, resourceName);
562            String res = getResourceNames().iterator().next();
563            rm = serviceType.compare(resourceName, res);
564        }
565
566        return rm;
567    }
568
569    /**
570     * Returns an XML string representing the rule.
571     *
572     * @return an XML string representing the rule.
573     * @supported.api
574     */
575    public String toXML() {
576        StringBuilder answer = new StringBuilder(100);
577        answer.append("\n").append("<Rule");
578        if (ruleName != null) {
579            answer.append(" name=\"");
580            answer.append(XMLUtils.escapeSpecialCharacters(ruleName));
581            answer.append("\">");
582        } else {
583            answer.append(">");
584        }
585
586        answer.append("\n").append("<ServiceName name=\"");
587        answer.append(XMLUtils.escapeSpecialCharacters(serviceTypeName));
588        answer.append("\" />");
589
590        if (applicationName != null) {
591            answer.append("\n").append("<")
592                .append(PolicyManager.POLICY_RULE_APPLICATION_NAME_NODE)
593                .append(" name=\"")
594                .append(XMLUtils.escapeSpecialCharacters(applicationName))
595                .append("\" />");
596        }
597
598        if (resourceNames != null) {
599            for (String resourceName : resourceNames) {
600                answer.append("\n").append("<ResourceName name=\"");
601                answer.append(
602                    XMLUtils.escapeSpecialCharacters(resourceName));
603                answer.append("\" />");
604            }
605        }
606
607        Set actionNames = new HashSet();
608        actionNames.addAll(actions.keySet());
609
610        Iterator actionNamesIter = actionNames.iterator();
611        while (actionNamesIter.hasNext()) {
612            String actionName = (String) actionNamesIter.next();
613            answer.append("\n").append("<AttributeValuePair>");
614            answer.append("\n").append("<Attribute name=\"");
615            answer.append(XMLUtils.escapeSpecialCharacters(actionName));
616            answer.append("\" />");
617            Set values = (Set) actions.get(actionName);
618
619            if (values.size() > 0) {
620                Iterator items = values.iterator();
621                while (items.hasNext()) {
622                    answer.append("\n").append("<Value>");
623                    answer.append(
624                            XMLUtils.escapeSpecialCharacters(
625                            (String) items.next()));
626                    answer.append("</Value>");
627                }
628
629            }
630            answer.append("\n").append("</AttributeValuePair>");
631        }
632
633        answer.append("\n").append("</Rule>");
634        return (answer.toString());
635    }
636
637    /**
638     * Returns service type of this rules.
639     * @return service type of this rule
640     */
641    protected ServiceType getServiceType() {
642        return (serviceType);
643    }
644
645    /**
646     * Returns an XML respresentation of the rule with policy name to
647     * use in resource index tree.
648     * @param policyName policy name to use while creating xml representation
649     * @return an XML respresentation of the rule with policy name to
650     * use in resource index tree
651     */
652    protected String toResourcesXml(String policyName) {
653        StringBuffer beginning = new StringBuffer(100);
654        // "<PolicyCrossReferences name=\"" + serviceTypeName +
655        // "\" type=\"Resources\">"
656        beginning.append("<")
657                .append(PolicyManager.POLICY_INDEX_ROOT_NODE)
658                .append(" ")
659                .append(PolicyManager.POLICY_INDEX_ROOT_NODE_NAME_ATTR)
660                .append("=\"")
661                .append(serviceTypeName)
662                .append("\" ")
663                .append(PolicyManager.POLICY_INDEX_ROOT_NODE_TYPE_ATTR)
664                .append("=\"")
665                .append(PolicyManager.POLICY_INDEX_ROOT_NODE_TYPE_ATTR_RESOURCES_VALUE)
666                .append("\">");
667
668        String normalizedResName = null;
669        if ((resourceNames == null) || resourceNames.isEmpty()) {
670            normalizedResName = ResourceManager.EMPTY_RESOURCE_NAME;
671        } else {
672            normalizedResName = resourceNames.iterator().next();
673        }
674
675        String[] resources = serviceType.split(normalizedResName);
676        int n = resources.length;
677
678        StringBuilder middle = new StringBuilder(100);
679        // "<Reference name=\"" + resources[n-1]) +
680        // "\"><PolicyName name=\"" + policyName +
681        // "\"/></Reference>"
682        middle.append("<")
683                .append(PolicyManager.POLICY_INDEX_REFERENCE_NODE)
684                .append(" ")
685                .append(PolicyManager.POLICY_INDEX_REFERENCE_NODE_NAME_ATTR)
686                .append("=\"")
687                .append(resources[n - 1])
688                .append("\"><")
689                .append(PolicyManager.POLICY_INDEX_POLICYNAME_NODE)
690                .append(" ")
691                .append(PolicyManager.POLICY_INDEX_POLICYNAME_NODE_NAME_ATTR)
692                .append("=\"")
693                .append(policyName)
694                .append("\"/></")
695                .append(PolicyManager.POLICY_INDEX_REFERENCE_NODE)
696                .append(">");
697        String tmp = middle.toString();
698        for (int i = n - 2; i >= 0; i--) {
699            //tmp = "<Reference name=\"" + resources[i] +"\">" +
700            //    tmp + "</Reference>";
701            tmp = "<"
702                    + PolicyManager.POLICY_INDEX_REFERENCE_NODE
703                    + " "
704                    + PolicyManager.POLICY_INDEX_REFERENCE_NODE_NAME_ATTR
705                    + "=\""
706                    + resources[i]
707                    + "\">"
708                    + tmp
709                    + "</"
710                    + PolicyManager.POLICY_INDEX_REFERENCE_NODE
711                    + ">";
712        }
713
714        return (beginning
715                    + tmp
716                    + "</"
717                    + PolicyManager.POLICY_INDEX_ROOT_NODE
718                    + ">");
719    }
720
721    /**
722     * Returns xml string representation of the rule.
723     *
724     * @return xml string representation of the rule
725     */
726    @Override
727    public String toString() {
728        return (toXML());
729    }
730
731    /**
732     * Creates and returns a copy of this object. The returned
733     * <code>Rule</code> object will have the same rule
734     * name, resource, service name, and actions
735     * such that <code>x.clone().equals(x)</code> will be
736     * <code>true</code>. However <code>x.clone()</code>
737     * will not be the same as <code>x</code>, i.e.,
738     * <code>x.clone() != x</code>.
739     *
740     * @return a copy of this object
741     */
742    @Override
743    public Object clone() {
744        Rule answer = null;
745        try {
746            answer = (Rule) super.clone();
747        } catch (CloneNotSupportedException se) {
748            answer = new Rule();
749        }
750
751        answer.ruleName = ruleName;
752        answer.serviceTypeName = serviceTypeName;
753        answer.applicationName = applicationName;
754        answer.serviceType = serviceType;
755        answer.resourceNames = new HashSet();
756        if (resourceNames != null) {
757            answer.resourceNames.addAll(resourceNames);
758        }
759
760        // Copy the actions
761        answer.actions = new HashMap();
762        Iterator items = actions.keySet().iterator();
763        while (items.hasNext()) {
764            Object o = items.next();
765            Set set = (Set) actions.get(o);
766            HashSet aSet = new HashSet();
767            aSet.addAll(set);
768            answer.actions.put(o, aSet);
769        }
770
771        return (answer);
772    }
773
774    /**
775     * Returns action values given resource type, resource name and a set of
776     * action names  by matching the arguments to those of the rule object.
777     *
778     * @param resourceType resource type
779     * @param resourceName resource name
780     * @param actionNames a set of action names for which to compute values.
781     * Each element of the set should be a <code>String</code>
782     * valued action name
783     * @return a map of action values for actions
784     *         Each key of the map is a String valued action name
785     *         Each value of the map is a set of String values
786     * @throws NameNotFoundException if any name in <code>actionNames</code> is
787     *         not found in the rule.
788     */
789    Map getActionValues(String resourceType, String resourceName,
790            Set actionNames) throws NameNotFoundException {
791        Map actionValues = null;
792        if ((serviceTypeName.equalsIgnoreCase(resourceType)) && (actionNames != null)) {
793            ResourceMatch rm = isResourceMatch(resourceType, resourceName);
794            if (ResourceMatch.EXACT_MATCH.equals(rm) || ResourceMatch.WILDCARD_MATCH.equals(rm)) {
795                //if (ResourceMatch.EXACT_MATCH.equals(rm) ) {
796                actionValues = new HashMap();
797                Iterator actionIter = actionNames.iterator();
798                while (actionIter.hasNext()) {
799                    String actionName = (String) actionIter.next();
800                    Set values = getActionValues(actionName);
801                    if (values != null) {
802                        actionValues.put(actionName, values);
803                    }
804
805                }
806            }
807        }
808        return (actionValues);
809    }
810}