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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 package java.security;
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;
34 import java.util.Vector;
37 * {@code UnresolvedPermissionCollection} represents a specific {@code
38 * PermissionCollection} for storing {@link UnresolvedPermission} instances.
39 * Contained elements are grouped by their target type.
41 final class UnresolvedPermissionCollection extends PermissionCollection {
43 private static final long serialVersionUID = -7176153071733132400L;
45 private static final ObjectStreamField[] serialPersistentFields = {
46 new ObjectStreamField("permissions", Hashtable.class), };
48 // elements of the collection.
49 private transient Map klasses = new HashMap();
52 * Adds an unresolved permission to this {@code
53 * UnresolvedPermissionCollection}.
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}.
63 public void add(Permission permission) {
65 throw new SecurityException("collection is read-only");
67 if (permission == null || permission.getClass() != UnresolvedPermission.class) {
68 throw new IllegalArgumentException("Invalid permission: " + permission);
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);
77 klassMates.add(permission);
81 public Enumeration elements() {
82 Collection all = new ArrayList();
83 for (Iterator iter = klasses.values().iterator(); iter.hasNext();) {
84 all.addAll((Collection)iter.next());
86 return Collections.enumeration(all);
90 * Always returns {@code false}.
92 * @return always {@code false}
93 * @see UnresolvedPermission#implies(Permission).
95 public boolean implies(Permission permission) {
100 * Returns true if this collection contains unresolved permissions
101 * with the same classname as argument permission.
103 boolean hasUnresolved(Permission permission) {
104 return klasses.containsKey(permission.getClass().getName());
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.
116 * a kind of permissions to be resolved.
118 * an existing collection for storing resolved permissions.
119 * @return a collection containing resolved permissions (if any found)
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
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();
138 holder.add(resolved);
142 if (klassMates.size() == 0) {
143 klasses.remove(klass);
151 * Output fields via default mechanism.
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())));
160 ObjectOutputStream.PutField fields = out.putFields();
161 fields.put("permissions", permissions);
166 * Reads the object from stream and checks elements grouping for validity.
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
176 Map.Entry entry = (Map.Entry) iter.next();
177 String key = (String) entry.getKey();
178 Collection values = (Collection) entry.getValue();
180 for (Iterator iterator = values.iterator(); iterator.hasNext();) {
181 UnresolvedPermission element =
182 (UnresolvedPermission) iterator.next();
184 if (!element.getName().equals(key)) {
185 throw new InvalidObjectException("collection is corrupted");
188 klasses.put(key, new HashSet(values));