KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > osgi > service > application > ApplicationAdminPermission


1 /*
2  * $Header: /cvshome/build/org.osgi.service.application/src/org/osgi/service/application/ApplicationAdminPermission.java,v 1.34 2006/07/12 21:22:11 hargrave Exp $
3  *
4  * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18
19 package org.osgi.service.application;
20
21 import java.security.Permission JavaDoc;
22 import java.util.*;
23
24 import org.osgi.framework.*;
25
26 /**
27  * This class implements permissions for manipulating applications and
28  * their instances.
29  * <P>
30  * ApplicationAdminPermission can be targeted to applications that matches the
31  * specified filter.
32  * <P>
33  * ApplicationAdminPermission may be granted for different actions:
34  * <code>lifecycle</code>, <code>schedule</code> and <code>lock</code>.
35  * The permission <code>schedule</code> implies the permission
36  * <code>lifecycle</code>.
37  */

38 public class ApplicationAdminPermission extends Permission JavaDoc {
39     private static final long serialVersionUID = 1L;
40   
41     /**
42      * Allows the lifecycle management of the target applications.
43      */

44     public static final String JavaDoc LIFECYCLE_ACTION = "lifecycle";
45
46     /**
47      * Allows scheduling of the target applications. The permission to
48      * schedule an application implies that the scheduler can also
49      * manage the lifecycle of that application i.e. <code>schedule</code>
50      * implies <code>lifecycle</code>
51      */

52     public static final String JavaDoc SCHEDULE_ACTION = "schedule";
53
54     /**
55      * Allows setting/unsetting the locking state of the target applications.
56      */

57     public static final String JavaDoc LOCK_ACTION = "lock";
58
59     private ApplicationDescriptor applicationDescriptor;
60
61     /**
62      * Constructs an ApplicationAdminPermission. The <code>filter</code>
63      * specifies the target application. The <code>filter</code> is an
64      * LDAP-style filter, the recognized properties are <code>signer</code>
65      * and <code>pid</code>. The pattern specified in the <code>signer</code>
66      * is matched with the Distinguished Name chain used to sign the application.
67      * Wildcards in a DN are not matched according to the filter string rules,
68      * but according to the rules defined for a DN chain. The attribute
69      * <code>pid</code> is matched with the PID of the application according to
70      * the filter string rules.
71      * <p>
72      * If the <code>filter</code> is <code>null</code> then it matches
73      * <code>"*"</code>. If
74      * <code>actions</code> is <code>"*"</code> then it identifies all the
75      * possible actions.
76      *
77      * @param filter
78      * filter to identify application. The value <code>null</code>
79      * is equivalent to <code>"*"</code> and it indicates "all application".
80      * @param actions
81      * comma-separated list of the desired actions granted on the
82      * applications or "*" means all the actions. It must not be
83      * <code>null</code>. The order of the actions in the list is
84      * not significant.
85      * @throws InvalidSyntaxException
86      * is thrown if the specified <code>filter</code> is not syntactically
87      * correct.
88      *
89      * @exception NullPointerException
90      * is thrown if the actions parameter is <code>null</code>
91      *
92      * @see ApplicationDescriptor
93      * @see org.osgi.framework.AdminPermission
94      */

95     public ApplicationAdminPermission(String JavaDoc filter, String JavaDoc actions) throws InvalidSyntaxException {
96         super(filter == null ? "*" : filter);
97         
98         if( filter == null )
99             filter = "*";
100         
101         if( actions == null )
102             throw new NullPointerException JavaDoc( "Action string cannot be null!" );
103         
104         this.applicationDescriptor = null;
105         this.filter = (filter == null ? "*" : filter);
106         this.actions = actions;
107
108         if( !filter.equals( "*" ) && !filter.equals( "<<SELF>>" ) )
109             FrameworkUtil.createFilter( this.filter ); // check if the filter is valid
110
init();
111     }
112     
113     /**
114      * This contructor should be used when creating <code>ApplicationAdminPermission</code>
115      * instance for <code>checkPermission</code> call.
116      * @param application the tareget of the operation, it must not be <code>null</code>
117      * @param actions the required operation. it must not be <code>null</code>
118      * @throws NullPointerException if any of the arguments is null.
119      */

120     public ApplicationAdminPermission(ApplicationDescriptor application, String JavaDoc actions) {
121         super(application.getApplicationId());
122                 
123         if( application == null || actions == null )
124             throw new NullPointerException JavaDoc( "ApplicationDescriptor and action string cannot be null!" );
125         
126         this.filter = application.getApplicationId();
127         this.applicationDescriptor = application;
128         this.actions = actions;
129         
130         init();
131     }
132     
133     /**
134      * This method can be used in the {@link java.security.ProtectionDomain}
135      * implementation in the <code>implies</code> method to insert the
136      * application ID of the current application into the permission being
137      * checked. This enables the evaluation of the
138      * <code>&lt;&lt;SELF&gt;&gt;</code> pseudo targets.
139      * @param applicationId the ID of the current application.
140      * @return the permission updated with the ID of the current application
141      */

142     public ApplicationAdminPermission setCurrentApplicationId(String JavaDoc applicationId) {
143         ApplicationAdminPermission newPerm = null;
144         
145         if( this.applicationDescriptor == null ) {
146             try {
147                 newPerm = new ApplicationAdminPermission( this.filter, this.actions );
148             }catch( InvalidSyntaxException e ) {
149                 throw new RuntimeException JavaDoc( "Internal error" ); /* this can never happen */
150             }
151         }
152         else
153             newPerm = new ApplicationAdminPermission( this.applicationDescriptor, this.actions );
154         
155         newPerm.applicationID = applicationId;
156         
157         return newPerm;
158     }
159
160     /**
161      * Checks if the specified <code>permission</code> is implied by this permission.
162      * The method returns true under the following conditions:
163      * <UL>
164      * <LI> This permission was created by specifying a filter (see {@link #ApplicationAdminPermission(String, String)})
165      * <LI> The implied <code>otherPermission</code> was created for a particular {@link ApplicationDescriptor}
166      * (see {@link #ApplicationAdminPermission(ApplicationDescriptor, String)})
167      * <LI> The <code>filter</code> of this permission mathes the <code>ApplicationDescriptor</code> specified
168      * in the <code>otherPermission</code>. If the filter in this permission is the
169      * <code>&lt;&lt;SELF&gt;&gt;</code> pseudo target, then the currentApplicationId set in the
170      * <code>otherPermission</code> is compared to the application Id of the target
171      * <code>ApplicationDescriptor</code>.
172      * <LI> The list of permitted actions in this permission contains all actions required in the
173      * <code>otherPermission</code>
174      * </UL>
175      * Otherwise the method returns false.
176      * @param otherPermission the implied permission
177      * @return true if this permission implies the <code>otherPermission</code>, false otherwise.
178      */

179   public boolean implies(Permission JavaDoc otherPermission) {
180       if( otherPermission == null )
181         return false;
182         
183       if(!(otherPermission instanceof ApplicationAdminPermission))
184           return false;
185
186       ApplicationAdminPermission other = (ApplicationAdminPermission) otherPermission;
187
188       if( !filter.equals("*") ) {
189         if( other.applicationDescriptor == null )
190             return false;
191         
192         if( filter.equals( "<<SELF>>") ) {
193             if( other.applicationID == null )
194                 return false; /* it cannot be, this might be a bug */
195             
196             if( !other.applicationID.equals( other.applicationDescriptor.getApplicationId() ) )
197                 return false;
198         }
199         else {
200             Hashtable props = new Hashtable();
201             props.put( "pid", other.applicationDescriptor.getApplicationId() );
202             props.put( "signer", new SignerWrapper( other.applicationDescriptor ) );
203                         
204             Filter flt = getFilter();
205             if( flt == null )
206                 return false;
207             
208             if( !flt.match( props ) )
209                 return false;
210         }
211       }
212       
213       if( !actionsVector.containsAll( other.actionsVector ) )
214         return false;
215       
216       return true;
217   }
218
219   public boolean equals(Object JavaDoc with) {
220     if( with == null || !(with instanceof ApplicationAdminPermission) )
221         return false;
222     
223     ApplicationAdminPermission other = (ApplicationAdminPermission)with;
224     
225     // Compare actions:
226
if( other.actionsVector.size() != actionsVector.size() )
227         return false;
228     
229     for( int i=0; i != actionsVector.size(); i++ )
230         if( !other.actionsVector.contains( actionsVector.get( i ) ) )
231             return false;
232     
233     
234     return equal(this.filter, other.filter ) && equal(this.applicationDescriptor, other.applicationDescriptor)
235             && equal(this.applicationID, other.applicationID);
236   }
237   
238   /**
239    * Compares parameters for equality. If both object are null, they are considered
240    * equal.
241    * @param a object to compare
242    * @param b other object to compare
243    * @return true if both objects are equal or both are null
244    */

245   private static boolean equal(Object JavaDoc a, Object JavaDoc b) {
246       // This equation is true if both references are null or both point
247
// to the same object. In both cases they are considered as equal.
248
if( a == b ) {
249           return true;
250       }
251       
252       return a.equals(b);
253   }
254
255   public int hashCode() {
256       int hc = 0;
257       for( int i=0; i != actionsVector.size(); i++ )
258           hc ^= ((String JavaDoc)actionsVector.get( i )).hashCode();
259       hc ^= (null == this.filter )? 0 : this.filter.hashCode();
260       hc ^= (null == this.applicationDescriptor) ? 0 : this.applicationDescriptor.hashCode();
261       hc ^= (null == this.applicationID) ? 0 : this.applicationID.hashCode();
262       return hc;
263   }
264
265   /**
266    * Returns the actions of this permission.
267    * @return the actions specified when this permission was created
268    */

269   public String JavaDoc getActions() {
270     return actions;
271   }
272
273   private String JavaDoc applicationID;
274
275   private static final Vector ACTIONS = new Vector();
276   private Vector actionsVector;
277   private final String JavaDoc filter;
278   private final String JavaDoc actions;
279   private Filter appliedFilter = null;
280   
281   static {
282       ACTIONS.add(LIFECYCLE_ACTION);
283       ACTIONS.add(SCHEDULE_ACTION);
284       ACTIONS.add(LOCK_ACTION);
285   }
286
287   private static Vector actionsVector(String JavaDoc actions) {
288       Vector v = new Vector();
289       StringTokenizer t = new StringTokenizer(actions.toUpperCase(), ",");
290       while (t.hasMoreTokens()) {
291           String JavaDoc action = t.nextToken().trim();
292           v.add(action.toLowerCase());
293       }
294       
295       if( v.contains( SCHEDULE_ACTION ) && !v.contains( LIFECYCLE_ACTION ) )
296           v.add( LIFECYCLE_ACTION );
297       
298       return v;
299   }
300   
301
302   private static class SignerWrapper extends Object JavaDoc {
303     private String JavaDoc pattern;
304     private ApplicationDescriptor appDesc;
305     
306     public SignerWrapper(String JavaDoc pattern) {
307         this.pattern = pattern;
308     }
309     
310     SignerWrapper(ApplicationDescriptor appDesc) {
311         this.appDesc = appDesc;
312     }
313     
314     public boolean equals(Object JavaDoc o) {
315         if (!(o instanceof SignerWrapper))
316             return false;
317         SignerWrapper other = (SignerWrapper) o;
318         ApplicationDescriptor matchAppDesc = (ApplicationDescriptor) (appDesc != null ? appDesc : other.appDesc);
319         String JavaDoc matchPattern = appDesc != null ? other.pattern : pattern;
320         return matchAppDesc.matchDNChain(matchPattern);
321     }
322   }
323   
324   private void init() {
325         actionsVector = actionsVector( actions );
326
327         if ( actions.equals("*") )
328             actionsVector = actionsVector( LIFECYCLE_ACTION + "," + SCHEDULE_ACTION + "," + LOCK_ACTION );
329         else if (!ACTIONS.containsAll(actionsVector))
330       throw new IllegalArgumentException JavaDoc("Illegal action!");
331         
332         applicationID = null;
333   }
334   
335   private Filter getFilter() {
336     String JavaDoc transformedFilter = filter;
337     
338     if (appliedFilter == null) {
339         try {
340             int pos = filter.indexOf("signer"); //$NON-NLS-1$
341
if (pos != -1){
342             
343                 //there may be a signer attribute
344
StringBuffer JavaDoc filterBuf = new StringBuffer JavaDoc(filter);
345                 int numAsteriskFound = 0; //use as offset to replace in buffer
346

347                 int walkbackPos; //temp pos
348

349                 //find occurences of (signer= and escape out *'s
350
while (pos != -1) {
351
352                     //walk back and look for '(' to see if this is an attr
353
walkbackPos = pos-1;
354                     
355                     //consume whitespace
356
while(walkbackPos >= 0 && Character.isWhitespace(filter.charAt(walkbackPos))) {
357                         walkbackPos--;
358                     }
359                     if (walkbackPos <0) {
360                         //filter is invalid - FilterImpl will throw error
361
break;
362                     }
363                     
364                     //check to see if we have unescaped '('
365
if (filter.charAt(walkbackPos) != '(' || (walkbackPos > 0 && filter.charAt(walkbackPos-1) == '\\')) {
366                         //'(' was escaped or not there
367
pos = filter.indexOf("signer",pos+6); //$NON-NLS-1$
368
continue;
369                     }
370                     pos+=6; //skip over 'signer'
371

372                     //found signer - consume whitespace before '='
373
while (Character.isWhitespace(filter.charAt(pos))) {
374                         pos++;
375                     }
376
377                     //look for '='
378
if (filter.charAt(pos) != '=') {
379                         //attr was signerx - keep looking
380
pos = filter.indexOf("signer",pos); //$NON-NLS-1$
381
continue;
382                     }
383                     pos++; //skip over '='
384

385                     //found signer value - escape '*'s
386
while (!(filter.charAt(pos) == ')' && filter.charAt(pos-1) != '\\')) {
387                         if (filter.charAt(pos) == '*') {
388                             filterBuf.insert(pos+numAsteriskFound,'\\');
389                             numAsteriskFound++;
390                         }
391                         pos++;
392                     }
393
394                     //end of signer value - look for more?
395
pos = filter.indexOf("signer",pos); //$NON-NLS-1$
396
} //end while (pos != -1)
397
transformedFilter = filterBuf.toString();
398             } //end if (pos != -1)
399

400             appliedFilter = FrameworkUtil.createFilter( transformedFilter );
401         } catch (InvalidSyntaxException e) {
402             //we will return null
403
}
404     }
405     return appliedFilter;
406   }
407 }
408
Popular Tags