Source code: com/sun/xacml/cond/GeneralSetFunction.java
1
2 /*
3 * @(#)GeneralSetFunction.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
44 import java.util.Collections;
45 import java.util.HashMap;
46 import java.util.HashSet;
47 import java.util.Iterator;
48 import java.util.List;
49 import java.util.Set;
50
51
52 /**
53 * Specific <code>SetFunction</code> class that supports all of the
54 * general-purpose set functions: type-intersection and type-union.
55 *
56 * @since 1.2
57 * @author Seth Proctor
58 */
59 public class GeneralSetFunction extends SetFunction
60 {
61
62 // private identifiers for the supported functions
63 private static final int ID_BASE_INTERSECTION = 0;
64 private static final int ID_BASE_UNION = 1;
65
66 // mapping of function name to its associated id and parameter type
67 private static HashMap idMap;
68 private static HashMap typeMap;
69
70 /**
71 * Static initializer that sets up the paramater info for all the
72 * supported functions.
73 */
74 static {
75 idMap = new HashMap();
76 typeMap = new HashMap();
77
78 idMap.put(NAME_BASE_INTERSECTION, new Integer(ID_BASE_INTERSECTION));
79 idMap.put(NAME_BASE_UNION, new Integer(ID_BASE_UNION));
80
81 for (int i = 0; i < baseTypes.length; i++) {
82 String baseName = FUNCTION_NS + simpleTypes[i];
83 String baseType = baseTypes[i];
84
85 idMap.put(baseName + NAME_BASE_INTERSECTION,
86 new Integer(ID_BASE_INTERSECTION));
87 idMap.put(baseName + NAME_BASE_UNION,
88 new Integer(ID_BASE_UNION));
89
90 typeMap.put(baseName + NAME_BASE_INTERSECTION, baseType);
91 typeMap.put(baseName + NAME_BASE_UNION, baseType);
92 }
93 };
94
95 /**
96 * Constructor that is used to create one of the general-purpose standard
97 * set functions. The name supplied must be one of the standard XACML
98 * functions supported by this class, including the full namespace,
99 * otherwise an exception is thrown. Look in <code>SetFunction</code>
100 * for details about the supported names.
101 *
102 * @param functionName the name of the function to create
103 *
104 * @throws IllegalArgumentException if the function is unknown
105 */
106 public GeneralSetFunction(String functionName) {
107 super(functionName, getId(functionName), getArgumentType(functionName),
108 getArgumentType(functionName), true);
109 }
110
111 /**
112 * Constructor that is used to create instances of general-purpose set
113 * functions for new (non-standard) datatypes. This is equivalent to
114 * using the <code>getInstance</code> methods in <code>SetFunction</code>
115 * and is generally only used by the run-time configuration code.
116 *
117 * @param functionName the name of the new function
118 * @param datatype the full identifier for the supported datatype
119 * @param functionType which kind of Set function, based on the
120 * <code>NAME_BASE_*</code> fields
121 */
122 public GeneralSetFunction(String functionName, String datatype,
123 String functionType) {
124 super(functionName, getId(functionType), datatype, datatype, true);
125 }
126
127 /**
128 * Private helper that returns the internal identifier used for the
129 * given standard function.
130 */
131 private static int getId(String functionName) {
132 Integer id = (Integer)(idMap.get(functionName));
133
134 if (id == null)
135 throw new IllegalArgumentException("unknown set function " +
136 functionName);
137
138 return id.intValue();
139 }
140
141 /**
142 * Private helper that returns the argument type for the given standard
143 * function. Note that this doesn't check on the return value since the
144 * method always is called after getId, so we assume that the function
145 * is present.
146 */
147 private static String getArgumentType(String functionName) {
148 return (String)(typeMap.get(functionName));
149 }
150
151 /**
152 * Returns a <code>Set</code> containing all the function identifiers
153 * supported by this class.
154 *
155 * @return a <code>Set</code> of <code>String</code>s
156 */
157 public static Set getSupportedIdentifiers() {
158 return Collections.unmodifiableSet(idMap.keySet());
159 }
160
161 /**
162 * Evaluates the function, using the specified parameters.
163 *
164 * @param inputs a <code>List</code> of <code>Evaluatable</code>
165 * objects representing the arguments passed to the function
166 * @param context an <code>EvaluationCtx</code> so that the
167 * <code>Evaluatable</code> objects can be evaluated
168 * @return an <code>EvaluationResult</code> representing the
169 * function's result
170 */
171 public EvaluationResult evaluate(List inputs, EvaluationCtx context) {
172
173 // Evaluate the arguments
174 AttributeValue [] argValues = new AttributeValue[inputs.size()];
175 EvaluationResult evalResult = evalArgs(inputs, context, argValues);
176 if (evalResult != null)
177 return evalResult;
178
179 // setup the two bags we'll be using
180 BagAttribute [] bags = new BagAttribute[2];
181 bags[0] = (BagAttribute)(argValues[0]);
182 bags[1] = (BagAttribute)(argValues[1]);
183
184 AttributeValue result = null;
185 Set set = new HashSet();
186
187 switch(getFunctionId()) {
188
189 // *-intersection takes two bags of the same type and returns
190 // a bag of that type
191 case ID_BASE_INTERSECTION:
192 // create a bag with the common elements of both inputs, removing
193 // all duplicate values
194
195 Iterator it = bags[0].iterator();
196
197 // find all the things in bags[0] that are also in bags[1]
198 while (it.hasNext()) {
199 AttributeValue value = (AttributeValue)(it.next());
200 if (bags[1].contains(value)) {
201 // sets won't allow duplicates, so this addition is ok
202 set.add(value);
203 }
204 }
205
206 result = new BagAttribute(bags[0].getType(), set);
207
208 break;
209
210 // *-union takes two bags of the same type and returns a bag of
211 // that type
212 case ID_BASE_UNION:
213 // create a bag with all the elements from both inputs, removing
214 // all duplicate values
215
216 Iterator it0 = bags[0].iterator();
217 while (it0.hasNext()) {
218 // first off, add all elements from the first bag...the set
219 // will ignore all duplicates
220 set.add(it0.next());
221 }
222
223 Iterator it1 = bags[1].iterator();
224 while (it1.hasNext()) {
225 // now add all the elements from the second bag...again, all
226 // duplicates will be ignored by the set
227 set.add(it1.next());
228 }
229
230 result = new BagAttribute(bags[0].getType(), set);
231
232 break;
233 }
234
235 return new EvaluationResult(result);
236 }
237
238 }