001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /**
019: * @author Alexey V. Varlamov
020: * @version $Revision$
021: */package java.security;
022:
023: import java.io.IOException;
024: import java.io.InvalidObjectException;
025: import java.io.ObjectInputStream;
026: import java.io.ObjectOutputStream;
027: import java.io.ObjectStreamField;
028: import java.util.ArrayList;
029: import java.util.Collection;
030: import java.util.Collections;
031: import java.util.Enumeration;
032: import java.util.HashMap;
033: import java.util.HashSet;
034: import java.util.Hashtable;
035: import java.util.Iterator;
036: import java.util.Map;
037: import java.util.Vector;
038:
039: import org.apache.harmony.security.internal.nls.Messages;
040:
041: /**
042: * Specific PermissionCollection for storing UnresolvedPermissions. Contained
043: * elements are grouped by their target type.
044: *
045: */
046: final class UnresolvedPermissionCollection extends PermissionCollection {
047:
048: /**
049: * @com.intel.drl.spec_ref
050: */
051: private static final long serialVersionUID = -7176153071733132400L;
052:
053: private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
054: "permissions", Hashtable.class), }; //$NON-NLS-1$
055:
056: // elements of the collection.
057: private transient Map klasses = new HashMap();
058:
059: /**
060: * Adds an unresolved permission to the collection.
061: *
062: * @see java.security.PermissionCollection#add(java.security.Permission)
063: */
064: public void add(Permission permission) {
065: if (isReadOnly()) {
066: throw new SecurityException(Messages
067: .getString("security.15")); //$NON-NLS-1$
068: }
069: if (permission == null
070: || permission.getClass() != UnresolvedPermission.class) {
071: throw new IllegalArgumentException(Messages.getString(
072: "security.16", //$NON-NLS-1$
073: permission));
074: }
075: synchronized (klasses) {
076: String klass = permission.getName();
077: Collection klassMates = (Collection) klasses.get(klass);
078: if (klassMates == null) {
079: klassMates = new HashSet();
080: klasses.put(klass, klassMates);
081: }
082: klassMates.add(permission);
083: }
084: }
085:
086: /**
087: * Returns enumeration over collection elements.
088: *
089: * @see java.security.PermissionCollection#elements()
090: */
091: public Enumeration elements() {
092: Collection all = new ArrayList();
093: for (Iterator iter = klasses.values().iterator(); iter
094: .hasNext();) {
095: all.addAll((Collection) iter.next());
096: }
097: return Collections.enumeration(all);
098: }
099:
100: /**
101: * Always returns false.
102: *
103: * @see java.security.UnresolvedPermission#implies(Permission)
104: */
105: public boolean implies(Permission permission) {
106: return false;
107: }
108:
109: /**
110: * Returns true if this collection contains unresolved permissions
111: * with the same classname as argument permission.
112: */
113: boolean hasUnresolved(Permission permission) {
114: return klasses.containsKey(permission.getClass().getName());
115: }
116:
117: /**
118: * Resolves all permissions of the same class as the specified target
119: * permission and adds them to the specified collection. If passed
120: * collection is <code>null</code> and some unresolved permissions were
121: * resolved, an appropriate new collection is instantiated and used. All
122: * resolved permissions are removed from this unresolved collection, and
123: * collection with resolved ones is returned.
124: *
125: * @param target - a kind of permissions to be resolved
126: * @param holder - an existing collection for storing resolved permissions
127: * @return a collection containing resolved permissions (if any found)
128: */
129: PermissionCollection resolveCollection(Permission target,
130: PermissionCollection holder) {
131: String klass = target.getClass().getName();
132: if (klasses.containsKey(klass)) {
133: synchronized (klasses) {
134: Collection klassMates = (Collection) klasses.get(klass);
135: for (Iterator iter = klassMates.iterator(); iter
136: .hasNext();) {
137: UnresolvedPermission element = (UnresolvedPermission) iter
138: .next();
139: Permission resolved = element.resolve(target
140: .getClass());
141: if (resolved != null) {
142: if (holder == null) {
143: holder = target.newPermissionCollection();
144: if (holder == null) {
145: holder = new PermissionsHash();
146: }
147: }
148: holder.add(resolved);
149: iter.remove();
150: }
151: }
152: if (klassMates.size() == 0) {
153: klasses.remove(klass);
154: }
155: }
156: }
157: return holder;
158: }
159:
160: /**
161: * @com.intel.drl.spec_ref
162: *
163: * Output fields via default mechanism.
164: */
165: private void writeObject(java.io.ObjectOutputStream out)
166: throws IOException {
167: Hashtable permissions = new Hashtable();
168: for (Iterator iter = klasses.entrySet().iterator(); iter
169: .hasNext();) {
170: Map.Entry entry = (Map.Entry) iter.next();
171: String key = (String) entry.getKey();
172: permissions.put(key, new Vector(((Collection) entry
173: .getValue())));
174: }
175: ObjectOutputStream.PutField fields = out.putFields();
176: fields.put("permissions", permissions); //$NON-NLS-1$
177: out.writeFields();
178: }
179:
180: /**
181: * @com.intel.drl.spec_ref
182: *
183: * Reads the object from stream and checks elements grouping for validity.
184: */
185: private void readObject(java.io.ObjectInputStream in)
186: throws IOException, ClassNotFoundException {
187: ObjectInputStream.GetField fields = in.readFields();
188: Map permissions = (Map) fields.get("permissions", null); //$NON-NLS-1$
189: klasses = new HashMap();
190: synchronized (klasses) {
191: for (Iterator iter = permissions.entrySet().iterator(); iter
192: .hasNext();) {
193: Map.Entry entry = (Map.Entry) iter.next();
194: String key = (String) entry.getKey();
195: Collection values = (Collection) entry.getValue();
196:
197: for (Iterator iterator = values.iterator(); iterator
198: .hasNext();) {
199: UnresolvedPermission element = (UnresolvedPermission) iterator
200: .next();
201:
202: if (!element.getName().equals(key)) {
203: throw new InvalidObjectException(Messages
204: .getString("security.22")); //$NON-NLS-1$
205: }
206: }
207: klasses.put(key, new HashSet(values));
208: }
209: }
210: }
211: }
|