| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package java.security; |
| |
| import java.io.IOException; |
| import java.io.InvalidObjectException; |
| import java.io.ObjectInputStream; |
| import java.io.ObjectOutputStream; |
| import java.io.ObjectStreamField; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.Enumeration; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Hashtable; |
| import java.util.Iterator; |
| import java.util.Map; |
| import java.util.Vector; |
| |
| /** |
| * {@code UnresolvedPermissionCollection} represents a specific {@code |
| * PermissionCollection} for storing {@link UnresolvedPermission} instances. |
| * Contained elements are grouped by their target type. |
| */ |
| final class UnresolvedPermissionCollection extends PermissionCollection { |
| |
| private static final long serialVersionUID = -7176153071733132400L; |
| |
| private static final ObjectStreamField[] serialPersistentFields = { |
| new ObjectStreamField("permissions", Hashtable.class), }; |
| |
| // elements of the collection. |
| private transient Map klasses = new HashMap(); |
| |
| /** |
| * Adds an unresolved permission to this {@code |
| * UnresolvedPermissionCollection}. |
| * |
| * @param permission |
| * the permission to be added. |
| * @throws SecurityException |
| * if this collection is read only. |
| * @throws IllegalArgumentException |
| * if {@code permission} is {@code null} or not an {@code |
| * UnresolvedPermission}. |
| */ |
| public void add(Permission permission) { |
| if (isReadOnly()) { |
| throw new SecurityException("collection is read-only"); |
| } |
| if (permission == null || permission.getClass() != UnresolvedPermission.class) { |
| throw new IllegalArgumentException("Invalid permission: " + permission); |
| } |
| synchronized (klasses) { |
| String klass = permission.getName(); |
| Collection klassMates = (Collection)klasses.get(klass); |
| if (klassMates == null) { |
| klassMates = new HashSet(); |
| klasses.put(klass, klassMates); |
| } |
| klassMates.add(permission); |
| } |
| } |
| |
| public Enumeration elements() { |
| Collection all = new ArrayList(); |
| for (Iterator iter = klasses.values().iterator(); iter.hasNext();) { |
| all.addAll((Collection)iter.next()); |
| } |
| return Collections.enumeration(all); |
| } |
| |
| /** |
| * Always returns {@code false}. |
| * |
| * @return always {@code false} |
| * @see UnresolvedPermission#implies(Permission). |
| */ |
| public boolean implies(Permission permission) { |
| return false; |
| } |
| |
| /** |
| * Returns true if this collection contains unresolved permissions |
| * with the same classname as argument permission. |
| */ |
| boolean hasUnresolved(Permission permission) { |
| return klasses.containsKey(permission.getClass().getName()); |
| } |
| |
| /** |
| * Resolves all permissions of the same class as the specified target |
| * permission and adds them to the specified collection. If passed |
| * collection is {@code null} and some unresolved permissions were resolved, |
| * an appropriate new collection is instantiated and used. All resolved |
| * permissions are removed from this unresolved collection, and collection |
| * with resolved ones is returned. |
| * |
| * @param target |
| * a kind of permissions to be resolved. |
| * @param holder |
| * an existing collection for storing resolved permissions. |
| * @return a collection containing resolved permissions (if any found) |
| */ |
| PermissionCollection resolveCollection(Permission target, |
| PermissionCollection holder) { |
| String klass = target.getClass().getName(); |
| if (klasses.containsKey(klass)) { |
| synchronized (klasses) { |
| Collection klassMates = (Collection)klasses.get(klass); |
| for (Iterator iter = klassMates.iterator(); iter.hasNext();) { |
| UnresolvedPermission element = (UnresolvedPermission)iter |
| .next(); |
| Permission resolved = element.resolve(target.getClass()); |
| if (resolved != null) { |
| if (holder == null) { |
| holder = target.newPermissionCollection(); |
| if (holder == null) { |
| holder = new PermissionsHash(); |
| } |
| } |
| holder.add(resolved); |
| iter.remove(); |
| } |
| } |
| if (klassMates.size() == 0) { |
| klasses.remove(klass); |
| } |
| } |
| } |
| return holder; |
| } |
| |
| /** |
| * Output fields via default mechanism. |
| */ |
| private void writeObject(java.io.ObjectOutputStream out) throws IOException { |
| Hashtable permissions = new Hashtable(); |
| for (Iterator iter = klasses.entrySet().iterator(); iter.hasNext();) { |
| Map.Entry entry = (Map.Entry) iter.next(); |
| String key = (String) entry.getKey(); |
| permissions.put(key, new Vector(((Collection) entry.getValue()))); |
| } |
| ObjectOutputStream.PutField fields = out.putFields(); |
| fields.put("permissions", permissions); |
| out.writeFields(); |
| } |
| |
| /** |
| * Reads the object from stream and checks elements grouping for validity. |
| */ |
| private void readObject(java.io.ObjectInputStream in) throws IOException, |
| ClassNotFoundException { |
| ObjectInputStream.GetField fields = in.readFields(); |
| Map permissions = (Map)fields.get("permissions", null); |
| klasses = new HashMap(); |
| synchronized (klasses) { |
| for (Iterator iter = permissions.entrySet().iterator(); iter |
| .hasNext();) { |
| Map.Entry entry = (Map.Entry) iter.next(); |
| String key = (String) entry.getKey(); |
| Collection values = (Collection) entry.getValue(); |
| |
| for (Iterator iterator = values.iterator(); iterator.hasNext();) { |
| UnresolvedPermission element = |
| (UnresolvedPermission) iterator.next(); |
| |
| if (!element.getName().equals(key)) { |
| throw new InvalidObjectException("collection is corrupted"); |
| } |
| } |
| klasses.put(key, new HashSet(values)); |
| } |
| } |
| } |
| } |