KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > osgi > service > permissionadmin > PermissionInfo


1 /*
2  * $Header: /cvshome/build/org.osgi.service.permissionadmin/src/org/osgi/service/permissionadmin/PermissionInfo.java,v 1.16 2006/06/16 16:31:44 hargrave Exp $
3  *
4  * Copyright (c) OSGi Alliance (2001, 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.permissionadmin;
20
21 /**
22  * Permission representation used by the Permission Admin service.
23  *
24  * <p>
25  * This class encapsulates three pieces of information: a Permission <i>type
26  * </i> (class name), which must be a subclass of
27  * <code>java.security.Permission</code>, and the <i>name </i> and <i>actions
28  * </i> arguments passed to its constructor.
29  *
30  * <p>
31  * In order for a permission represented by a <code>PermissionInfo</code> to be
32  * instantiated and considered during a permission check, its Permission class
33  * must be available from the system classpath or an exported package. This
34  * means that the instantiation of a permission represented by a
35  * <code>PermissionInfo</code> may be delayed until the package containing its
36  * Permission class has been exported by a bundle.
37  *
38  * @version $Revision: 1.16 $
39  */

40 public class PermissionInfo {
41     private String JavaDoc type;
42     private String JavaDoc name;
43     private String JavaDoc actions;
44
45     /**
46      * Constructs a <code>PermissionInfo</code> from the specified type, name, and
47      * actions.
48      *
49      * @param type The fully qualified class name of the permission represented
50      * by this <code>PermissionInfo</code>. The class must be a subclass
51      * of <code>java.security.Permission</code> and must define a
52      * 2-argument constructor that takes a <i>name </i> string and an
53      * <i>actions </i> string.
54      *
55      * @param name The permission name that will be passed as the first argument
56      * to the constructor of the <code>Permission</code> class identified
57      * by <code>type</code>.
58      *
59      * @param actions The permission actions that will be passed as the second
60      * argument to the constructor of the <code>Permission</code> class
61      * identified by <code>type</code>.
62      *
63      * @throws java.lang.NullPointerException if <code>type</code> is
64      * <code>null</code>.
65      * @throws java.lang.IllegalArgumentException if <code>action</code> is not
66      * <code>null</code> and <code>name</code> is <code>null</code>.
67      */

68     public PermissionInfo(String JavaDoc type, String JavaDoc name, String JavaDoc actions) {
69         this.type = type;
70         this.name = name;
71         this.actions = actions;
72         if (type == null) {
73             throw new NullPointerException JavaDoc("type is null");
74         }
75         if ((name == null) && (actions != null)) {
76             throw new IllegalArgumentException JavaDoc("name missing");
77         }
78     }
79
80     /**
81      * Constructs a <code>PermissionInfo</code> object from the specified encoded
82      * <code>PermissionInfo</code> string. White space in the encoded
83      * <code>PermissionInfo</code> string is ignored.
84      *
85      *
86      * @param encodedPermission The encoded <code>PermissionInfo</code>.
87      * @see #getEncoded
88      * @throws java.lang.IllegalArgumentException If the
89      * <code>encodedPermission</code> is not properly formatted.
90      */

91     public PermissionInfo(String JavaDoc encodedPermission) {
92         if (encodedPermission == null) {
93             throw new NullPointerException JavaDoc("missing encoded permission");
94         }
95         if (encodedPermission.length() == 0) {
96             throw new IllegalArgumentException JavaDoc("empty encoded permission");
97         }
98         try {
99             char[] encoded = encodedPermission.toCharArray();
100             int length = encoded.length;
101             int pos = 0;
102             
103             /* skip whitespace */
104             while (Character.isWhitespace(encoded[pos])) {
105                 pos++;
106             }
107             
108             /* the first character must be '(' */
109             if (encoded[pos] != '(') {
110                 throw new IllegalArgumentException JavaDoc(
111                         "expecting open parenthesis");
112             }
113             pos++;
114
115             /* skip whitespace */
116             while (Character.isWhitespace(encoded[pos])) {
117                 pos++;
118             }
119             
120             /* type is not quoted or encoded */
121             int begin = pos;
122             while (!Character.isWhitespace(encoded[pos]) && (encoded[pos] != ')')) {
123                 pos++;
124             }
125             if (pos == begin || encoded[begin] == '"') {
126                 throw new IllegalArgumentException JavaDoc("expecting type");
127             }
128             this.type = new String JavaDoc(encoded, begin, pos - begin);
129             
130             /* skip whitespace */
131             while (Character.isWhitespace(encoded[pos])) {
132                 pos++;
133             }
134             
135             /* type may be followed by name which is quoted and encoded */
136             if (encoded[pos] == '"') {
137                 pos++;
138                 begin = pos;
139                 while (encoded[pos] != '"') {
140                     if (encoded[pos] == '\\') {
141                         pos++;
142                     }
143                     pos++;
144                 }
145                 this.name = unescapeString(encoded, begin, pos);
146                 pos++;
147
148                 if (Character.isWhitespace(encoded[pos])) {
149                     /* skip whitespace */
150                     while (Character.isWhitespace(encoded[pos])) {
151                         pos++;
152                     }
153                     
154                     /* name may be followed by actions which is quoted and encoded */
155                     if (encoded[pos] == '"') {
156                         pos++;
157                         begin = pos;
158                         while (encoded[pos] != '"') {
159                             if (encoded[pos] == '\\') {
160                                 pos++;
161                             }
162                             pos++;
163                         }
164                         this.actions = unescapeString(encoded, begin, pos);
165                         pos++;
166
167                         /* skip whitespace */
168                         while (Character.isWhitespace(encoded[pos])) {
169                             pos++;
170                         }
171                     }
172                 }
173             }
174             
175             /* the final character must be ')' */
176             char c = encoded[pos];
177             pos++;
178             while ((pos < length) && Character.isWhitespace(encoded[pos])) {
179                 pos++;
180             }
181             if ((c != ')') || (pos != length)) {
182                 throw new IllegalArgumentException JavaDoc("expecting close parenthesis");
183             }
184         }
185         catch (ArrayIndexOutOfBoundsException JavaDoc e) {
186             throw new IllegalArgumentException JavaDoc("parsing terminated abruptly");
187         }
188     }
189
190     /**
191      * Returns the string encoding of this <code>PermissionInfo</code> in a form
192      * suitable for restoring this <code>PermissionInfo</code>.
193      *
194      * <p>
195      * The encoded format is:
196      *
197      * <pre>
198      * (type)
199      * </pre>
200      *
201      * or
202      *
203      * <pre>
204      * (type &quot;name&quot;)
205      * </pre>
206      *
207      * or
208      *
209      * <pre>
210      * (type &quot;name&quot; &quot;actions&quot;)
211      * </pre>
212      *
213      * where <i>name</i> and <i>actions</i> are strings that are encoded for
214      * proper parsing. Specifically, the <code>"</code>,<code>\</code>, carriage
215      * return, and linefeed characters are escaped using <code>\"</code>,
216      * <code>\\</code>,<code>\r</code>, and <code>\n</code>, respectively.
217      *
218      * <p>
219      * The encoded string contains no leading or trailing whitespace
220      * characters. A single space character is used between <i>type</i> and
221      * &quot;<i>name</i>&quot; and between &quot;<i>name</i>&quot; and &quot;<i>actions</i>&quot;.
222      *
223      * @return The string encoding of this <code>PermissionInfo</code>.
224      */

225     public final String JavaDoc getEncoded() {
226         StringBuffer JavaDoc output = new StringBuffer JavaDoc(
227                 8
228                         + type.length()
229                         + ((((name == null) ? 0 : name.length()) + ((actions == null) ? 0
230                                 : actions.length())) << 1));
231         output.append('(');
232         output.append(type);
233         if (name != null) {
234             output.append(" \"");
235             escapeString(name, output);
236             if (actions != null) {
237                 output.append("\" \"");
238                 escapeString(actions, output);
239             }
240             output.append('\"');
241         }
242         output.append(')');
243         return output.toString();
244     }
245
246     /**
247      * Returns the string representation of this <code>PermissionInfo</code>. The
248      * string is created by calling the <code>getEncoded</code> method on this
249      * <code>PermissionInfo</code>.
250      *
251      * @return The string representation of this <code>PermissionInfo</code>.
252      */

253     public String JavaDoc toString() {
254         return getEncoded();
255     }
256
257     /**
258      * Returns the fully qualified class name of the permission represented by
259      * this <code>PermissionInfo</code>.
260      *
261      * @return The fully qualified class name of the permission represented by
262      * this <code>PermissionInfo</code>.
263      */

264     public final String JavaDoc getType() {
265         return type;
266     }
267
268     /**
269      * Returns the name of the permission represented by this
270      * <code>PermissionInfo</code>.
271      *
272      * @return The name of the permission represented by this
273      * <code>PermissionInfo</code>, or <code>null</code> if the permission
274      * does not have a name.
275      */

276     public final String JavaDoc getName() {
277         return name;
278     }
279
280     /**
281      * Returns the actions of the permission represented by this
282      * <code>PermissionInfo</code>.
283      *
284      * @return The actions of the permission represented by this
285      * <code>PermissionInfo</code>, or <code>null</code> if the permission
286      * does not have any actions associated with it.
287      */

288     public final String JavaDoc getActions() {
289         return actions;
290     }
291
292     /**
293      * Determines the equality of two <code>PermissionInfo</code> objects.
294      *
295      * This method checks that specified object has the same type, name and
296      * actions as this <code>PermissionInfo</code> object.
297      *
298      * @param obj The object to test for equality with this
299      * <code>PermissionInfo</code> object.
300      * @return <code>true</code> if <code>obj</code> is a <code>PermissionInfo</code>,
301      * and has the same type, name and actions as this
302      * <code>PermissionInfo</code> object; <code>false</code> otherwise.
303      */

304     public boolean equals(Object JavaDoc obj) {
305         if (obj == this) {
306             return true;
307         }
308         if (!(obj instanceof PermissionInfo)) {
309             return false;
310         }
311         PermissionInfo other = (PermissionInfo) obj;
312         if (!type.equals(other.type) || ((name == null) ^ (other.name == null))
313                 || ((actions == null) ^ (other.actions == null))) {
314             return false;
315         }
316         if (name != null) {
317             if (actions != null) {
318                 return name.equals(other.name) && actions
319                         .equals(other.actions);
320             }
321             else {
322                 return name.equals(other.name);
323             }
324         }
325         else {
326             return true;
327         }
328     }
329
330     /**
331      * Returns the hash code value for this object.
332      *
333      * @return A hash code value for this object.
334      */

335     public int hashCode() {
336         int hash = type.hashCode();
337         if (name != null) {
338             hash ^= name.hashCode();
339             if (actions != null) {
340                 hash ^= actions.hashCode();
341             }
342         }
343         return hash;
344     }
345
346     /**
347      * This escapes the quotes, backslashes, \n, and \r in the string using a
348      * backslash and appends the newly escaped string to a StringBuffer.
349      */

350     private static void escapeString(String JavaDoc str, StringBuffer JavaDoc output) {
351         int len = str.length();
352         for (int i = 0; i < len; i++) {
353             char c = str.charAt(i);
354             switch (c) {
355                 case '"' :
356                 case '\\' :
357                     output.append('\\');
358                     output.append(c);
359                     break;
360                 case '\r' :
361                     output.append("\\r");
362                     break;
363                 case '\n' :
364                     output.append("\\n");
365                     break;
366                 default :
367                     output.append(c);
368                     break;
369             }
370         }
371     }
372
373     /**
374      * Takes an encoded character array and decodes it into a new String.
375      */

376     private static String JavaDoc unescapeString(char[] str, int begin, int end) {
377         StringBuffer JavaDoc output = new StringBuffer JavaDoc(end - begin);
378         for (int i = begin; i < end; i++) {
379             char c = str[i];
380             if (c == '\\') {
381                 i++;
382                 if (i < end) {
383                     c = str[i];
384                     switch (c) {
385                         case '"' :
386                         case '\\' :
387                             break;
388                         case 'r' :
389                             c = '\r';
390                             break;
391                         case 'n' :
392                             c = '\n';
393                             break;
394                         default :
395                             c = '\\';
396                             i--;
397                             break;
398                     }
399                 }
400             }
401             output.append(c);
402         }
403         
404         return output.toString();
405     }
406 }
407
Popular Tags