KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > security > jacc > EJBMethodPermission


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 package javax.security.jacc;
25
26 import java.security.*;
27 import java.lang.reflect.*;
28
29 import java.util.HashMap JavaDoc;
30 import java.io.IOException JavaDoc;
31 import java.io.ObjectStreamField JavaDoc;
32
33
34 /**
35  * Class for EJB method permissions.
36  * <P>
37  * The name of an EJBMethodPermission contains the value of the
38  * ejb-name element in the application's deployment descriptor
39  * that identifies the target EJB.
40  * <P>
41  * The actions of an EJBMethodPermission identifies the methods of
42  * the EJB to which the permission applies.
43  * <P>
44  * Implementations of this class MAY implement newPermissionCollection or
45  * inherit its implementation from the super class.
46  *
47  * @see java.security.Permission
48  *
49  * @author Ron Monzillo
50  * @author Gary Ellison
51  *
52  */

53
54 public final class EJBMethodPermission extends Permission
55 implements java.io.Serializable JavaDoc
56 {
57
58     private static final String JavaDoc interfaceKeys[] =
59          { "Local", "LocalHome", "Remote", "Home", "ServiceEndpoint" };
60
61     private static HashMap JavaDoc interfaceHash = new HashMap JavaDoc();
62     static {
63     for (int i=0; i<interfaceKeys.length; i++)
64         interfaceHash.put(interfaceKeys[i], new Integer JavaDoc(i));
65     };
66
67     private transient int methodInterface;
68
69     private transient String JavaDoc otherMethodInterface = null;
70
71     private transient String JavaDoc methodName;
72
73     private transient String JavaDoc methodParams;
74
75     private transient String JavaDoc actions;
76
77     private transient int hashCodeValue = 0;
78
79     private static final long serialVersionUID = 1L;
80
81    /**
82     * The serialized fields of this permission are defined below. Whether
83     * or not the serialized fields correspond to actual (private) fields
84     * is an implementation decision.
85     * @serialField actions String
86     * the canonicalized actions string (as returned by getActions).
87     */

88     private static final ObjectStreamField JavaDoc[] serialPersistentFields = {
89         new ObjectStreamField JavaDoc("actions", java.lang.String JavaDoc.class)
90     };
91
92    /**
93     * Creates a new EJBMethodPermission with the specified name and actions.
94     * <P>
95     * The name contains the value of the ejb-name element corresponding
96     * to an EJB in the application's deployment descriptor.
97     * <P>
98     * The actions contains a methodSpec. The syntax of the actions parameter
99     * is defined as follows:
100     * <P><Pre>
101     * methodNameSpec ::= methodName | emptyString
102     *
103     * methodInterfaceName ::= String
104     *
105     * methodInterfaceSpec ::= methodInterfaceName | emptyString
106     *
107     * typeName ::= typeName | typeName []
108     *
109     * methodParams ::= typeName | methodParams comma typeName
110     *
111     * methodParamsSpec ::= emptyString | methodParams
112     *
113     * methodSpec ::= null |
114     * methodNameSpec |
115     * methodNameSpec comma methodInterfaceName |
116     * methodNameSpec comma methodInterfaceSpec comma methodParamsSpec
117     * </Pre><P>
118     * A MethodInterfaceName is a non-empty String and should contain a
119     * method-intf value as defined for use in EJB deployment descriptors.
120     * An implementation must be flexible such that it supports additional
121     * interface names especially if they are standardized by the EJB
122     * Specification. The EJB Specification currently defines the following
123     * method-intf values:
124     * <P><Pre>
125     * { "Home", "LocalHome", "Remote", "Local", "ServiceEndpoint" }
126     * </Pre><P>
127     * A null or empty string methodSpec indicates that the permission applies
128     * to all methods of the EJB. A methodSpec with a methodNameSpec of the
129     * empty string matches all methods of the EJB that match the
130     * methodInterface and methodParams elements of the methodSpec.
131     * <P>
132     * A methodSpec with a methodInterfaceSpec of the
133     * empty string matches all methods of the EJB that match the
134     * methodNameSpec and methodParamsSpec elements of the methodSpec.
135     * <P>
136     * A methodSpec without a methodParamsSpec matches all methods
137     * of the EJB that match the methodNameSpec and methodInterface elements
138     * of the methodSpec.
139     * <P>
140     * The order of the typeNames in methodParams array must match
141     * the order of occurence of the corresponding parameters in the method
142     * signature of the target method(s). Each typeName in the methodParams
143     * must contain the canonical form of the corresponding parameter's typeName
144     * as defined by the getActions method. A methodSpec with
145     * an empty methodParamsSpec matches all 0 argument methods of the
146     * EJB that match the methodNameSpec and methodInterfaceSpec elements of
147     * the methodSpec.
148     * <P>
149     * @param name of the EJB to which the permission pertains.
150     * <P>
151     * @param actions identifies the methods of the EJB to which the
152     * permission pertains.
153     */

154     
155     public EJBMethodPermission(String JavaDoc name, String JavaDoc actions)
156     {
157     super(name);
158     setMethodSpec(actions);
159     }
160
161    /**
162     * Creates a new EJBMethodPermission with name corresponding to
163     * the EJBName and actions composed from methodName, methodInterface,
164     * and methodParams.
165     * <P>
166     * @param EJBName The string representation of the name of the EJB as it
167     * appears in the corresponding ejb-name element in the deployment
168     * descriptor.
169     * <P>
170     * @param methodName A string that may be used to indicate the method of
171     * the EJB to which the permission pertains. A value of null or ""
172     * indicates that the permission pertains to all methods that
173     * match the other parameters of the permission specification
174     * without consideration of method name.
175     * <P>
176     * @param methodInterface A string that may be used to specify the EJB
177     * interface to which the permission pertains. A value of null or "",
178     * indicates that the permission pertains to all methods that match the
179     * other parameters of the permission specification without consideration
180     * of the interface they occur on.
181     * <P>
182     * @param methodParams An array of strings that may be used to specify
183     * (by typeNames) the parameter signature of the target methods. The
184     * order of the typeNames in methodParams array must match
185     * the order of occurence of the corresponding parameters
186     * in the method signature of the target method(s). Each typeName in
187     * the methodParams array must contain the canonical form of the
188     * corresponding parameter's typeName as defined by the getActions method.
189     * An empty methodParams array is used to represent
190     * a method signature with no arguments. A value of null indicates that
191     * the permission pertains to all methods that match the other
192     * parameters of the permission specification without consideration
193     * of method signature.
194     */

195
196     public EJBMethodPermission(String JavaDoc EJBName, String JavaDoc methodName,
197     String JavaDoc methodInterface, String JavaDoc[] methodParams)
198     {
199     super(EJBName);
200     setMethodSpec(methodName,methodInterface,methodParams);
201     }
202
203    /**
204     * Creates a new EJBMethodPermission with name corresponding to the
205     * EJBName and actions composed from methodInterface, and the
206     * Method object.
207     * <P>
208     * A container uses this constructor prior to checking if a caller
209     * has permission to call the method of an EJB.
210     * <P>
211     * @param EJBName The string representation of the name of the EJB as it
212     * appears in the corresponding ejb-name element in the deployment
213     * descriptor.
214     * <P>
215     * @param methodInterface A string that may be used to specify the EJB
216     * interface to which the permission pertains.
217     * A value of null or "", indicates that the permission pertains
218     * to all methods that match the other parameters of the
219     * permission specification without consideration of the
220     * interface they occur on.
221     * <P>
222     * @param method an instance of the Java.lang.reflect.Method class
223     * corresponding to the method that the container is trying to determine
224     * whether the caller has permission to access. This value must not be
225     * null.
226     */

227
228     public EJBMethodPermission(String JavaDoc EJBName, String JavaDoc methodInterface,
229         Method method)
230     {
231     super(EJBName);
232     setMethodSpec(methodInterface,method);
233     }
234
235    /**
236     * Checks two EJBMethodPermission objects for equality.
237     * EJBMethodPermission objects are equivalent if they have case sensitive
238     * equivalent name and actions values.
239     * <P>
240     * Two Permission objects, P1 and P2, are equivalent if and only if
241     * P1.implies(P2) && P2.implies(P1).
242     * <P>
243     * @param o the EJBMethodPermission object being tested for equality
244     * with this EJBMethodPermission
245     * <P>
246     * @return true if the argument EJBMethodPermission object is equivalent
247     * to this EJBMethodPermission.
248     */

249
250     public boolean equals(Object JavaDoc o)
251     {
252     if (o == null || ! (o instanceof EJBMethodPermission JavaDoc)) return false;
253
254     EJBMethodPermission JavaDoc that = (EJBMethodPermission JavaDoc) o;
255
256     if (!this.getName().equals(that.getName())) return false;
257
258     if (this.methodName != null) {
259         if (that.methodName == null ||
260         !this.methodName.equals(that.methodName)) return false;
261     }
262     else if (that.methodName != null) return false;
263
264     if (this.methodInterface != that.methodInterface) return false;
265
266     if (this.methodInterface == -2 &&
267         !this.otherMethodInterface.equals(that.otherMethodInterface))
268         return false;
269
270     if (this.methodParams != null) {
271         if (that.methodParams == null ||
272         !this.methodParams.equals(that.methodParams)) return false;
273     }
274     else if (that.methodParams != null) return false;
275
276     return true;
277     }
278
279    /**
280     * Returns a String containing a canonical representation of the actions
281     * of this EJBMethodPermission. The Canonical form of the actions
282     * of an EJBMethodPermission is described by the following syntax
283     * description.
284     * <P><Pre>
285     * methodNameSpec ::= methodName | emptyString
286     *
287     * methodInterfaceName ::= String
288     *
289     * methodInterfaceSpec ::= methodInterfaceName | emptyString
290     *
291     * typeName ::= typeName | typeName []
292     *
293     * methodParams ::= typeName | methodParams comma typeName
294     *
295     * methodParamsSpec ::= emptyString | methodParams
296     *
297     * methodSpec ::= null |
298     * methodName |
299     * methodNameSpec comma methodInterfaceName |
300     * methodNameSpec comma methodInterfaceSpec comma methodParamsSpec
301     * </Pre><P>
302     * The canonical form of each typeName must begin with the fully qualified Java
303     * name of the corresponding parameter's type. The canonical form of a typeName
304     * for an array parameter is the fully qualified Java name of the array's component
305     * type followed by as many instances of the string "[]" as there are dimensions
306     * to the array. No additional characters (e.g. blanks) may occur in the
307     * canonical form.
308     * <P>
309     * A MethodInterfaceName is a non-empty String and should contain a
310     * method-intf value as defined for use in EJB deployment descriptors.
311     * An implementation must be flexible such that it supports additional
312     * interface names especially if they are standardized by the EJB
313     * Specification. The EJB Specification currently defines the following
314     * method-intf values:
315     * <P><Pre>
316     * { "Home", "LocalHome", "Remote", "Local", "ServiceEndpoint" }
317     * </Pre><P>
318     * @return a String containing the canonicalized actions of this
319     * EJBMethodPermission.
320     */

321
322     public String JavaDoc getActions()
323     {
324     if (this.actions == null) {
325
326         String JavaDoc iSpec = (this.methodInterface == -1 ? null :
327                 (this.methodInterface < 0 ?
328                  this.otherMethodInterface :
329                  interfaceKeys[this.methodInterface]));
330         
331         if (this.methodName == null) {
332         if (iSpec == null) {
333             if (this.methodParams != null)
334             this.actions = "," + this.methodParams;
335         }
336         else if (this.methodParams == null)
337             this.actions = "," + iSpec;
338         else this.actions = "," + iSpec + this.methodParams;
339         }
340         else if (iSpec == null) {
341         if (this.methodParams == null) this.actions = this.methodName;
342         else this.actions = this.methodName + "," + this.methodParams;
343         }
344         else if (this.methodParams == null) {
345         this.actions = this.methodName + "," + iSpec;
346         }
347         else this.actions = this.methodName + "," + iSpec +
348              this.methodParams;
349     }
350
351     return this.actions;
352     }
353
354    /**
355     * Returns the hash code value for this EJBMethodPermission. The properties
356     * of the returned hash code must be as follows: <p>
357     * <ul>
358     * <li> During the lifetime of a Java application, the hashCode method
359     * must return the same integer value every time it is called on a
360     * EJBMethodPermission object. The value returned by hashCode for a
361     * particular EJBMethodPermission need not remain consistent from
362     * one execution of an application to another.
363     * <li> If two EJBMethodPermission objects are equal according to the
364     * equals method, then calling the hashCode method on each of the two
365     * Permission objects must produce the same integer result (within an
366     * application).
367     * </ul>
368     * <P>
369     * @return the integer hash code value for this object.
370     */

371
372     public int hashCode()
373     {
374     if (hashCodeValue == 0) {
375
376         String JavaDoc hashInput;
377         String JavaDoc actions = this.getActions();
378
379         if (actions == null) hashInput = this.getName();
380         else hashInput = new String JavaDoc(this.getName() + " " + actions);
381
382         hashCodeValue = hashInput.hashCode();
383     }
384     return this.hashCodeValue;
385     }
386
387     /**
388      * Determines if the argument Permission is "implied by" this
389      * EJBMethodPermission. For this to be the case, <p>
390      * <ul>
391      * <li> The argument must be an instanceof EJBMethodPermission
392      * <li> with name equivalent to that of this EJBMethodPermission, and
393      * <li> the methods to which the argument permission applies (as defined
394      * in its actions) must be a subset of the methods to which this
395      * EJBMethodPermission applies (as defined in its actions).
396      * </ul>
397      * <P>
398      * The argument permission applies to a subset of the methods to which
399      * this permission applies if all of the following conditions are met.
400      * <ul>
401      * <li> the method name component of the methodNameSpec of this
402      * permission is null, the empty string, or
403      * equivalent to the method name of the argument permission, and
404      * <li> the method interface component of the methodNameSpec of this
405      * permission is null, the empty string, or equivalent to the
406      * method interface of the argument permission, and
407      * <li> the method parameter list component of the methodNameSpec
408      * of this permission is null, the empty string, or equivalent
409      * to the method parameter list of the argument permission.
410      * </ul>
411      * <P>
412      * The name and actions comparisons described above are case sensitive.
413      * <P>
414      * @param permission "this" EJBMethodPermission is checked to see if
415      * it implies the argument permission.
416      * <P>
417      * @return true if the specified permission is implied by this object,
418      * false if not.
419      */

420     public boolean implies(Permission permission)
421     {
422     if (permission == null ||
423         ! (permission instanceof EJBMethodPermission JavaDoc)) return false;
424
425     EJBMethodPermission JavaDoc that = (EJBMethodPermission JavaDoc) permission;
426
427     if (!this.getName().equals(that.getName())) return false;
428         
429     if (this.methodName != null &&
430         (that.methodName == null ||
431          !this.methodName.equals(that.methodName))) return false;
432
433     if (this.methodInterface != -1 &&
434         (that.methodInterface == -1 ||
435         this.methodInterface != that.methodInterface)) return false;
436
437     if (this.methodInterface == -2 &&
438         !this.otherMethodInterface.equals(that.otherMethodInterface))
439         return false;
440
441     if (this.methodParams != null &&
442         (that.methodParams == null ||
443         !this.methodParams.equals(that.methodParams))) return false;
444
445     return true;
446     }
447
448     // ----------------- Private Methods ---------------------
449

450    /**
451      * readObject reads the serialized fields from the
452      * input stream and uses them to restore the permission.
453      * This method need not be implemented if establishing the
454      * values of the serialized fields (as is done by defaultReadObject)
455      * is sufficient to initialize the permission.
456      */

457     private synchronized void readObject(java.io.ObjectInputStream JavaDoc s)
458          throws IOException JavaDoc,ClassNotFoundException JavaDoc
459     {
460     setMethodSpec((String JavaDoc) s.readFields().get("actions",null));
461     }
462
463     /**
464      * writeObject is used to establish the values of the serialized fields
465      * before they are written to the output stream and need not be
466      * implemented if the values of the serialized fields are always
467      * available and up to date. The serialized fields are written to
468      * the output stream in the same form as they would be written
469      * by defaultWriteObject.
470      */

471     private synchronized void writeObject(java.io.ObjectOutputStream JavaDoc s)
472          throws IOException JavaDoc
473     {
474     s.putFields().put("actions",this.getActions());
475     s.writeFields();
476     }
477
478     private void setMethodSpec (String JavaDoc actions)
479     {
480     
481         String JavaDoc mInterface = null;
482
483     this.methodName = null;
484     this.methodParams = null;
485
486     if (actions != null) {
487
488         if (actions.length() > 0) {
489
490         int i = actions.indexOf(',');
491         if (i < 0) this.methodName = actions;
492         else if (i >= 0) {
493
494             if (i != 0) this.methodName = actions.substring(0,i);
495
496             if (actions.length() == i+1)
497             throw new
498                 IllegalArgumentException JavaDoc("illegal actions spec");
499
500             int j = actions.substring(i+1).indexOf(',');
501             if (j < 0) mInterface = actions.substring(i+1);
502             
503             else {
504             if (j > 0) mInterface = actions.substring(i+1,i+j+1);
505             this.methodParams = actions.substring(i+j+1);
506
507             if (this.methodParams.length() > 1 &&
508                 this.methodParams.endsWith(","))
509                 throw new
510                 IllegalArgumentException JavaDoc("illegal methodParam");
511             }
512         }
513         } else {
514         //canonical form of emptystring actions is null
515
actions = null;
516         }
517     }
518
519     this.methodInterface = validateInterface(mInterface);
520
521     if (this.methodInterface < -1)
522         this.otherMethodInterface = mInterface;
523
524     this.actions = actions;
525     }
526
527     private void setMethodSpec(String JavaDoc methodName,String JavaDoc mInterface,
528                    String JavaDoc[] methodParams)
529     {
530     if (methodName != null && methodName.indexOf(',') >= 0)
531         throw new IllegalArgumentException JavaDoc("illegal methodName");
532     
533     this.methodInterface = validateInterface(mInterface);
534
535     if (this.methodInterface < -1)
536         this.otherMethodInterface = mInterface;
537
538     if (methodParams != null) {
539
540         StringBuffer JavaDoc mParams = new StringBuffer JavaDoc(",");
541
542         for (int i=0; i<methodParams.length; i++) {
543         if (methodParams[i] == null ||
544             methodParams[i].indexOf(',') >= 0)
545             throw new IllegalArgumentException JavaDoc("illegal methodParam");
546         if (i == 0) mParams.append(methodParams[i]);
547         else mParams.append("," + methodParams[i]);
548         }
549         this.methodParams = mParams.toString();
550     }
551     else this.methodParams = null;
552
553     this.methodName = methodName;
554     }
555
556     private void setMethodSpec(String JavaDoc mInterface, Method method)
557     {
558     this.methodInterface = validateInterface(mInterface);
559
560     if (this.methodInterface < -1)
561         this.otherMethodInterface = mInterface;
562
563     this.methodName = method.getName();
564
565     Class JavaDoc[] params = method.getParameterTypes();
566  
567         StringBuffer JavaDoc mParams = new StringBuffer JavaDoc(",");
568
569     for (int i=0; i<params.length; i++) {
570
571         String JavaDoc pname = params[i].getName();
572         Class JavaDoc compType = params[i].getComponentType();
573
574         // Canonicalize parameter if it is an Array.
575
if (compType != null) {
576         String JavaDoc brackets = "[]";
577         while (compType.getComponentType() != null) {
578             compType = compType.getComponentType();
579             brackets = brackets + "[]";
580         }
581         pname = compType.getName() + brackets;
582         }
583
584         if (i == 0) mParams.append(pname);
585         else mParams.append("," + pname);
586     }
587
588         this.methodParams = mParams.toString();
589     }
590
591     private static int validateInterface (String JavaDoc methodInterface)
592     {
593     int result = -1;
594     if (methodInterface != null && methodInterface.length() > 0) {
595         Integer JavaDoc i = (Integer JavaDoc) interfaceHash.get(methodInterface);
596         if (i != null) result = i.intValue();
597         else result = -2;
598     }
599     return result;
600     }
601
602 }
603
Popular Tags