KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > osgi > service > condpermadmin > ConditionInfo


1 /*
2  * $Header: /cvshome/build/org.osgi.service.condpermadmin/src/org/osgi/service/condpermadmin/ConditionInfo.java,v 1.13 2006/06/16 16:31:37 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.condpermadmin;
20
21 import java.util.ArrayList JavaDoc;
22
23 /**
24  * Condition representation used by the Conditional Permission Admin service.
25  *
26  * <p>
27  * This class encapsulates two pieces of information: a Condition <i>type</i>
28  * (class name), which must implement <code>Condition</code>, and the
29  * arguments passed to its constructor.
30  *
31  * <p>
32  * In order for a Condition represented by a <code>ConditionInfo</code> to be
33  * instantiated and considered during a permission check, its Condition class
34  * must be available from the system classpath.
35  *
36  * <p>
37  * The Condition class must either:
38  * <ul>
39  * <li>Declare a public static <code>getCondition</code> method that takes a
40  * <code>Bundle</code> object and a <code>ConditionInfo</code> object as
41  * arguments. That method must return an object that implements the
42  * <code>Condition</code> interface.</li>
43  * <li>Implement the <code>Condition</code> interface and define a public
44  * constructor that takes a <code>Bundle</code> object and a
45  * <code>ConditionInfo</code> object as arguments.
46  * </ul>
47  *
48  * @version $Revision: 1.13 $
49  */

50 public class ConditionInfo {
51     private String JavaDoc type;
52     private String JavaDoc[] args;
53
54     /**
55      * Constructs a <code>ConditionInfo</code> from the specified type and
56      * args.
57      *
58      * @param type The fully qualified class name of the Condition represented
59      * by this <code>ConditionInfo</code>.
60      * @param args The arguments for the Condition. These arguments are
61      * available to the newly created Condition by calling the
62      * {@link #getArgs()} method.
63      * @throws java.lang.NullPointerException If <code>type</code> is
64      * <code>null</code>.
65      */

66     public ConditionInfo(String JavaDoc type, String JavaDoc[] args) {
67         this.type = type;
68         this.args = args != null ? args : new String JavaDoc[0];
69         if (type == null) {
70             throw new NullPointerException JavaDoc("type is null");
71         }
72     }
73
74     /**
75      * Constructs a <code>ConditionInfo</code> object from the specified
76      * encoded <code>ConditionInfo</code> string. White space in the encoded
77      * <code>ConditionInfo</code> string is ignored.
78      *
79      * @param encodedCondition The encoded <code>ConditionInfo</code>.
80      * @see #getEncoded
81      * @throws java.lang.IllegalArgumentException If the
82      * <code>encodedCondition</code> is not properly formatted.
83      */

84     public ConditionInfo(String JavaDoc encodedCondition) {
85         if (encodedCondition == null) {
86             throw new NullPointerException JavaDoc("missing encoded condition");
87         }
88         if (encodedCondition.length() == 0) {
89             throw new IllegalArgumentException JavaDoc("empty encoded condition");
90         }
91         try {
92             char[] encoded = encodedCondition.toCharArray();
93             int length = encoded.length;
94             int pos = 0;
95
96             /* skip whitespace */
97             while (Character.isWhitespace(encoded[pos])) {
98                 pos++;
99             }
100
101             /* the first character must be '[' */
102             if (encoded[pos] != '[') {
103                 throw new IllegalArgumentException JavaDoc("expecting open bracket");
104             }
105             pos++;
106
107             /* skip whitespace */
108             while (Character.isWhitespace(encoded[pos])) {
109                 pos++;
110             }
111
112             /* type is not quoted or encoded */
113             int begin = pos;
114             while (!Character.isWhitespace(encoded[pos])
115                     && (encoded[pos] != ']')) {
116                 pos++;
117             }
118             if (pos == begin || encoded[begin] == '"') {
119                 throw new IllegalArgumentException JavaDoc("expecting type");
120             }
121             this.type = new String JavaDoc(encoded, begin, pos - begin);
122
123             /* skip whitespace */
124             while (Character.isWhitespace(encoded[pos])) {
125                 pos++;
126             }
127
128             /* type may be followed by args which are quoted and encoded */
129             ArrayList JavaDoc argsList = new ArrayList JavaDoc();
130             while (encoded[pos] == '"') {
131                 pos++;
132                 begin = pos;
133                 while (encoded[pos] != '"') {
134                     if (encoded[pos] == '\\') {
135                         pos++;
136                     }
137                     pos++;
138                 }
139                 argsList.add(unescapeString(encoded, begin, pos));
140                 pos++;
141
142                 if (Character.isWhitespace(encoded[pos])) {
143                     /* skip whitespace */
144                     while (Character.isWhitespace(encoded[pos])) {
145                         pos++;
146                     }
147                 }
148             }
149             this.args = (String JavaDoc[]) argsList
150                     .toArray(new String JavaDoc[argsList.size()]);
151
152             /* the final character must be ']' */
153             char c = encoded[pos];
154             pos++;
155             while ((pos < length) && Character.isWhitespace(encoded[pos])) {
156                 pos++;
157             }
158             if ((c != ']') || (pos != length)) {
159                 throw new IllegalArgumentException JavaDoc("expecting close bracket");
160             }
161         }
162         catch (ArrayIndexOutOfBoundsException JavaDoc e) {
163             throw new IllegalArgumentException JavaDoc("parsing terminated abruptly");
164         }
165     }
166
167     /**
168      * Returns the string encoding of this <code>ConditionInfo</code> in a
169      * form suitable for restoring this <code>ConditionInfo</code>.
170      *
171      * <p>
172      * The encoding format is:
173      *
174      * <pre>
175      * [type &quot;arg0&quot; &quot;arg1&quot; ...]
176      * </pre>
177      *
178      * where <i>argN</i> are strings that are encoded for proper parsing.
179      * Specifically, the <code>"</code>, <code>\</code>, carriage return,
180      * and linefeed characters are escaped using <code>\"</code>,
181      * <code>\\</code>, <code>\r</code>, and <code>\n</code>,
182      * respectively.
183      *
184      * <p>
185      * The encoded string contains no leading or trailing whitespace characters.
186      * A single space character is used between type and "<i>arg0</i>" and
187      * between the arguments.
188      *
189      * @return The string encoding of this <code>ConditionInfo</code>.
190      */

191     public final String JavaDoc getEncoded() {
192         StringBuffer JavaDoc output = new StringBuffer JavaDoc();
193         output.append('[');
194         output.append(type);
195
196         for (int i = 0; i < args.length; i++) {
197             output.append(" \"");
198             escapeString(args[i], output);
199             output.append('\"');
200         }
201
202         output.append(']');
203
204         return output.toString();
205     }
206
207     /**
208      * Returns the string representation of this <code>ConditionInfo</code>.
209      * The string is created by calling the <code>getEncoded</code> method on
210      * this <code>ConditionInfo</code>.
211      *
212      * @return The string representation of this <code>ConditionInfo</code>.
213      */

214     public String JavaDoc toString() {
215         return getEncoded();
216     }
217
218     /**
219      * Returns the fully qualified class name of the condition represented by
220      * this <code>ConditionInfo</code>.
221      *
222      * @return The fully qualified class name of the condition represented by
223      * this <code>ConditionInfo</code>.
224      */

225     public final String JavaDoc getType() {
226         return type;
227     }
228
229     /**
230      * Returns arguments of this <code>ConditionInfo</code>.
231      *
232      * @return The arguments of this <code>ConditionInfo</code>. An empty
233      * array is returned if the <code>ConditionInfo</code> has no
234      * arguments.
235      */

236     public final String JavaDoc[] getArgs() {
237         return args;
238     }
239
240     /**
241      * Determines the equality of two <code>ConditionInfo</code> objects.
242      *
243      * This method checks that specified object has the same type and args as
244      * this <code>ConditionInfo</code> object.
245      *
246      * @param obj The object to test for equality with this
247      * <code>ConditionInfo</code> object.
248      * @return <code>true</code> if <code>obj</code> is a
249      * <code>ConditionInfo</code>, and has the same type and args as
250      * this <code>ConditionInfo</code> object; <code>false</code>
251      * otherwise.
252      */

253     public boolean equals(Object JavaDoc obj) {
254         if (obj == this) {
255             return true;
256         }
257
258         if (!(obj instanceof ConditionInfo)) {
259             return false;
260         }
261
262         ConditionInfo other = (ConditionInfo) obj;
263
264         if (!type.equals(other.type) || args.length != other.args.length)
265             return false;
266
267         for (int i = 0; i < args.length; i++) {
268             if (!args[i].equals(other.args[i]))
269                 return false;
270         }
271         return true;
272     }
273
274     /**
275      * Returns the hash code value for this object.
276      *
277      * @return A hash code value for this object.
278      */

279
280     public int hashCode() {
281         int hash = type.hashCode();
282
283         for (int i = 0; i < args.length; i++) {
284             hash ^= args[i].hashCode();
285         }
286         return hash;
287     }
288
289     /**
290      * This escapes the quotes, backslashes, \n, and \r in the string using a
291      * backslash and appends the newly escaped string to a StringBuffer.
292      */

293     private static void escapeString(String JavaDoc str, StringBuffer JavaDoc output) {
294         int len = str.length();
295         for (int i = 0; i < len; i++) {
296             char c = str.charAt(i);
297             switch (c) {
298                 case '"' :
299                 case '\\' :
300                     output.append('\\');
301                     output.append(c);
302                     break;
303                 case '\r' :
304                     output.append("\\r");
305                     break;
306                 case '\n' :
307                     output.append("\\n");
308                     break;
309                 default :
310                     output.append(c);
311                     break;
312             }
313         }
314     }
315
316     /**
317      * Takes an encoded character array and decodes it into a new String.
318      */

319     private static String JavaDoc unescapeString(char[] str, int begin, int end) {
320         StringBuffer JavaDoc output = new StringBuffer JavaDoc(end - begin);
321         for (int i = begin; i < end; i++) {
322             char c = str[i];
323             if (c == '\\') {
324                 i++;
325                 if (i < end) {
326                     c = str[i];
327                     switch (c) {
328                         case '"' :
329                         case '\\' :
330                             break;
331                         case 'r' :
332                             c = '\r';
333                             break;
334                         case 'n' :
335                             c = '\n';
336                             break;
337                         default :
338                             c = '\\';
339                             i--;
340                             break;
341                     }
342                 }
343             }
344             output.append(c);
345         }
346
347         return output.toString();
348     }
349 }
350
Popular Tags