Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/sun/xacml/cond/ConditionSetFunction.java


1   
2   /*
3    * @(#)ConditionSetFunction.java
4    *
5    * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
6    *
7    * Redistribution and use in source and binary forms, with or without
8    * modification, are permitted provided that the following conditions are met:
9    *
10   *   1. Redistribution of source code must retain the above copyright notice,
11   *      this list of conditions and the following disclaimer.
12   * 
13   *   2. Redistribution in binary form must reproduce the above copyright
14   *      notice, this list of conditions and the following disclaimer in the
15   *      documentation and/or other materials provided with the distribution.
16   *
17   * Neither the name of Sun Microsystems, Inc. or the names of contributors may
18   * be used to endorse or promote products derived from this software without
19   * specific prior written permission.
20   * 
21   * This software is provided "AS IS," without a warranty of any kind. ALL
22   * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
23   * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
24   * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
25   * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
26   * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
27   * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
28   * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
29   * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
30   * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
31   * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
32   *
33   * You acknowledge that this software is not designed or intended for use in
34   * the design, construction, operation or maintenance of any nuclear facility.
35   */
36  
37  package com.sun.xacml.cond;
38  
39  import com.sun.xacml.EvaluationCtx;
40  
41  import com.sun.xacml.attr.AttributeValue;
42  import com.sun.xacml.attr.BagAttribute;
43  import com.sun.xacml.attr.BooleanAttribute;
44  
45  import java.util.Collections;
46  import java.util.HashMap;
47  import java.util.HashSet;
48  import java.util.Iterator;
49  import java.util.List;
50  import java.util.Set;
51  
52  
53  /**
54   * Specific <code>SetFunction</code> class that supports all of the
55   * condition set functions: type-at-least-one-member-of, type-subset, and
56   * type-set-equals.
57   *
58   * @since 1.2
59   * @author Seth Proctor
60   */
61  public class ConditionSetFunction extends SetFunction
62  {
63  
64      // private identifiers for the supported functions
65      private static final int ID_BASE_AT_LEAST_ONE_MEMBER_OF = 0;
66      private static final int ID_BASE_SUBSET = 1;
67      private static final int ID_BASE_SET_EQUALS = 2;
68  
69      // mapping of function name to its associated id and parameter type
70      private static HashMap idMap;
71      private static HashMap typeMap;
72  
73      // the actual supported ids
74      private static Set supportedIds;
75  
76      /**
77       * Static initializer that sets up the paramater info for all the
78       * supported functions.
79       */
80      static {
81          idMap = new HashMap();
82          typeMap = new HashMap();
83  
84          for (int i = 0; i < baseTypes.length; i++) {
85              String baseName = FUNCTION_NS + simpleTypes[i];
86              String baseType = baseTypes[i];
87  
88              idMap.put(baseName + NAME_BASE_AT_LEAST_ONE_MEMBER_OF,
89                        new Integer(ID_BASE_AT_LEAST_ONE_MEMBER_OF));
90              idMap.put(baseName + NAME_BASE_SUBSET,
91                        new Integer(ID_BASE_SUBSET));
92              idMap.put(baseName + NAME_BASE_SET_EQUALS,
93                        new Integer(ID_BASE_SET_EQUALS));
94  
95              typeMap.put(baseName + NAME_BASE_AT_LEAST_ONE_MEMBER_OF, baseType);
96              typeMap.put(baseName + NAME_BASE_SUBSET, baseType);
97              typeMap.put(baseName + NAME_BASE_SET_EQUALS, baseType);
98          }
99  
100         supportedIds = Collections.
101             unmodifiableSet(new HashSet(idMap.keySet()));
102 
103         idMap.put(NAME_BASE_AT_LEAST_ONE_MEMBER_OF,
104                   new Integer(ID_BASE_AT_LEAST_ONE_MEMBER_OF));
105         idMap.put(NAME_BASE_SUBSET, new Integer(ID_BASE_SUBSET));
106         idMap.put(NAME_BASE_SET_EQUALS, new Integer(ID_BASE_SET_EQUALS));
107     };
108     
109     /**
110      * Constructor that is used to create one of the condition standard
111      * set functions. The name supplied must be one of the standard XACML
112      * functions supported by this class, including the full namespace,
113      * otherwise an exception is thrown. Look in <code>SetFunction</code>
114      * for details about the supported names.
115      *
116      * @param functionName the name of the function to create
117      *
118      * @throws IllegalArgumentException if the function is unknown
119      */
120     public ConditionSetFunction(String functionName) {
121         super(functionName, getId(functionName), getArgumentType(functionName),
122               BooleanAttribute.identifier, false);
123     }
124 
125     /**
126      * Constructor that is used to create instances of condition set
127      * functions for new (non-standard) datatypes. This is equivalent to
128      * using the <code>getInstance</code> methods in <code>SetFunction</code>
129      * and is generally only used by the run-time configuration code.
130      *
131      * @param functionName the name of the new function
132      * @param datatype the full identifier for the supported datatype
133      * @param functionType which kind of Set function, based on the
134      *                     <code>NAME_BASE_*</code> fields
135      */
136     public ConditionSetFunction(String functionName, String datatype,
137                                 String functionType) {
138         super(functionName, getId(functionName), datatype,
139               BooleanAttribute.identifier, false);
140     }
141 
142     /**
143      * Private helper that returns the internal identifier used for the
144      * given standard function.
145      */
146     private static int getId(String functionName) {
147         Integer id = (Integer)(idMap.get(functionName));
148 
149         if (id == null)
150             throw new IllegalArgumentException("unknown set function " +
151                                                functionName);
152 
153         return id.intValue();
154     }
155 
156     /**
157      * Private helper that returns the argument type for the given standard
158      * function. Note that this doesn't check on the return value since the
159      * method always is called after getId, so we assume that the function
160      * is present.
161      */
162     private static String getArgumentType(String functionName) {
163         return (String)(typeMap.get(functionName));
164     }
165 
166     /**
167      * Returns a <code>Set</code> containing all the function identifiers
168      * supported by this class.
169      *
170      * @return a <code>Set</code> of <code>String</code>s
171      */
172     public static Set getSupportedIdentifiers() {
173         return supportedIds;
174     }
175 
176     /**
177      * Evaluates the function, using the specified parameters.
178      *
179      * @param inputs a <code>List</code> of <code>Evaluatable</code>
180      *               objects representing the arguments passed to the function
181      * @param context an <code>EvaluationCtx</code> so that the
182      *                <code>Evaluatable</code> objects can be evaluated
183      * @return an <code>EvaluationResult</code> representing the
184      *         function's result
185      */
186     public EvaluationResult evaluate(List inputs, EvaluationCtx context) {
187 
188         // Evaluate the arguments
189         AttributeValue [] argValues = new AttributeValue[inputs.size()];
190         EvaluationResult evalResult = evalArgs(inputs, context, argValues);
191         if (evalResult != null)
192             return evalResult;
193 
194         // setup the two bags we'll be using
195         BagAttribute [] bags = new BagAttribute[2];
196         bags[0] = (BagAttribute)(argValues[0]);
197         bags[1] = (BagAttribute)(argValues[1]);
198 
199         AttributeValue result = null;
200         
201         switch(getFunctionId()) {
202             // *-at-least-one-member-of takes two bags of the same type and
203             // returns a boolean
204         case ID_BASE_AT_LEAST_ONE_MEMBER_OF:
205             // true if at least one element in the first argument is in the
206             // second argument (using the *-is-in semantics)
207 
208             result = BooleanAttribute.getFalseInstance();
209             Iterator it = bags[0].iterator();
210 
211             while (it.hasNext()) {
212                 if (bags[1].contains((AttributeValue)(it.next()))) {
213                     result = BooleanAttribute.getTrueInstance();
214                     break;
215                 }
216             }
217             
218             break;
219 
220             // *-set-equals takes two bags of the same type and returns
221             // a boolean
222         case ID_BASE_SUBSET:
223             // returns true if the first argument is a subset of the second
224             // argument (ie, all the elements in the first bag appear in
225             // the second bag) ... ignore all duplicate values in both
226             // input bags
227 
228             boolean subset = bags[1].containsAll(bags[0]);
229             result = BooleanAttribute.getInstance(subset);
230             
231             break;
232 
233             // *-set-equals takes two bags of the same type and returns
234             // a boolean
235         case ID_BASE_SET_EQUALS:
236 
237             // returns true if the two inputs contain the same elements
238             // discounting any duplicates in either input ... this is the same
239             // as applying the and function on the subset function with
240             // the two inputs, and then the two inputs reversed (ie, are the
241             // two inputs subsets of each other)
242 
243             boolean equals = (bags[1].containsAll(bags[0]) &&
244                               bags[0].containsAll(bags[1]));
245             result = BooleanAttribute.getInstance(equals);
246 
247             break;
248         }
249         
250         return new EvaluationResult(result);
251     }
252 
253 }