OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / libcore / luni / src / main / java / java / security / UnresolvedPermissionCollection.java
1 /*
2  *  Licensed to the Apache Software Foundation (ASF) under one or more
3  *  contributor license agreements.  See the NOTICE file distributed with
4  *  this work for additional information regarding copyright ownership.
5  *  The ASF licenses this file to You under the Apache License, Version 2.0
6  *  (the "License"); you may not use this file except in compliance with
7  *  the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  */
17
18 package java.security;
19
20 import java.io.IOException;
21 import java.io.InvalidObjectException;
22 import java.io.ObjectInputStream;
23 import java.io.ObjectOutputStream;
24 import java.io.ObjectStreamField;
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.Enumeration;
29 import java.util.HashMap;
30 import java.util.HashSet;
31 import java.util.Hashtable;
32 import java.util.Iterator;
33 import java.util.Map;
34 import java.util.Vector;
35
36 /**
37  * {@code UnresolvedPermissionCollection} represents a specific {@code
38  * PermissionCollection} for storing {@link UnresolvedPermission} instances.
39  * Contained elements are grouped by their target type.
40  */
41 final class UnresolvedPermissionCollection extends PermissionCollection {
42
43     private static final long serialVersionUID = -7176153071733132400L;
44
45     private static final ObjectStreamField[] serialPersistentFields = {
46         new ObjectStreamField("permissions", Hashtable.class), };
47
48     // elements of the collection.
49     private transient Map klasses = new HashMap();
50
51     /**
52      * Adds an unresolved permission to this {@code
53      * UnresolvedPermissionCollection}.
54      *
55      * @param permission
56      *            the permission to be added.
57      * @throws SecurityException
58      *             if this collection is read only.
59      * @throws IllegalArgumentException
60      *             if {@code permission} is {@code null} or not an {@code
61      *             UnresolvedPermission}.
62      */
63     public void add(Permission permission) {
64         if (isReadOnly()) {
65             throw new SecurityException("collection is read-only");
66         }
67         if (permission == null || permission.getClass() != UnresolvedPermission.class) {
68             throw new IllegalArgumentException("Invalid permission: " + permission);
69         }
70         synchronized (klasses) {
71             String klass = permission.getName();
72             Collection klassMates = (Collection)klasses.get(klass);
73             if (klassMates == null) {
74                 klassMates = new HashSet();
75                 klasses.put(klass, klassMates);
76             }
77             klassMates.add(permission);
78         }
79     }
80
81     public Enumeration elements() {
82         Collection all = new ArrayList();
83         for (Iterator iter = klasses.values().iterator(); iter.hasNext();) {
84             all.addAll((Collection)iter.next());
85         }
86         return Collections.enumeration(all);
87     }
88
89     /**
90      * Always returns {@code false}.
91      *
92      * @return always {@code false}
93      * @see UnresolvedPermission#implies(Permission).
94      */
95     public boolean implies(Permission permission) {
96         return false;
97     }
98
99     /**
100      * Returns true if this collection contains unresolved permissions
101      * with the same classname as argument permission.
102      */
103     boolean hasUnresolved(Permission permission) {
104         return klasses.containsKey(permission.getClass().getName());
105     }
106
107     /**
108      * Resolves all permissions of the same class as the specified target
109      * permission and adds them to the specified collection. If passed
110      * collection is {@code null} and some unresolved permissions were resolved,
111      * an appropriate new collection is instantiated and used. All resolved
112      * permissions are removed from this unresolved collection, and collection
113      * with resolved ones is returned.
114      *
115      * @param target
116      *            a kind of permissions to be resolved.
117      * @param holder
118      *            an existing collection for storing resolved permissions.
119      * @return a collection containing resolved permissions (if any found)
120      */
121     PermissionCollection resolveCollection(Permission target,
122                                            PermissionCollection holder) {
123         String klass = target.getClass().getName();
124         if (klasses.containsKey(klass)) {
125             synchronized (klasses) {
126                 Collection klassMates = (Collection)klasses.get(klass);
127                 for (Iterator iter = klassMates.iterator(); iter.hasNext();) {
128                     UnresolvedPermission element = (UnresolvedPermission)iter
129                         .next();
130                     Permission resolved = element.resolve(target.getClass());
131                     if (resolved != null) {
132                         if (holder == null) {
133                             holder = target.newPermissionCollection();
134                             if (holder == null) {
135                                 holder = new PermissionsHash();
136                             }
137                         }
138                         holder.add(resolved);
139                         iter.remove();
140                     }
141                 }
142                 if (klassMates.size() == 0) {
143                     klasses.remove(klass);
144                 }
145             }
146         }
147         return holder;
148     }
149
150     /**
151      * Output fields via default mechanism.
152      */
153     private void writeObject(java.io.ObjectOutputStream out) throws IOException {
154         Hashtable permissions = new Hashtable();
155         for (Iterator iter = klasses.entrySet().iterator(); iter.hasNext();) {
156             Map.Entry entry = (Map.Entry) iter.next();
157             String key = (String) entry.getKey();
158             permissions.put(key, new Vector(((Collection) entry.getValue())));
159         }
160         ObjectOutputStream.PutField fields = out.putFields();
161         fields.put("permissions", permissions);
162         out.writeFields();
163     }
164
165     /**
166      * Reads the object from stream and checks elements grouping for validity.
167      */
168     private void readObject(java.io.ObjectInputStream in) throws IOException,
169         ClassNotFoundException {
170         ObjectInputStream.GetField fields = in.readFields();
171         Map permissions = (Map)fields.get("permissions", null);
172         klasses = new HashMap();
173         synchronized (klasses) {
174             for (Iterator iter = permissions.entrySet().iterator(); iter
175                 .hasNext();) {
176                 Map.Entry entry = (Map.Entry) iter.next();
177                 String key = (String) entry.getKey();
178                 Collection values = (Collection) entry.getValue();
179
180                 for (Iterator iterator = values.iterator(); iterator.hasNext();) {
181                     UnresolvedPermission element =
182                             (UnresolvedPermission) iterator.next();
183
184                     if (!element.getName().equals(key)) {
185                         throw new InvalidObjectException("collection is corrupted");
186                     }
187                 }
188                 klasses.put(key, new HashSet(values));
189             }
190         }
191     }
192 }