Dan Creswell wrote:
What kind of thoughts are you after?

Appropriateness, code review, something else?

Ideas.

It would be nice to lock on each SocketPermission, however that isn't possible, it cannot be wrapped inside SocketPermissionCollection and the latter cannot be guaranteed to be used uniquely to synchronize the former.

I wanted to avoid creating a specific collection for only handling SocketPermission, but since it's SocketPermissionCollection doesn't do anything fancy and just iterates over all the SocketPermission's I might yet create a SocketPermission wrapper that implements a sensible equals and has it's own PermissionCollection, that uses a tryLock and skips SocketPermission's it can't obtain the lock and try again later.

Cheers,

Peter.
On 19 December 2011 05:59, Peter Firmstone <j...@zeus.net.au> wrote:
Thoughts?


/*
* 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 net.jini.security;

import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.security.Permission;
import java.security.PermissionCollection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import org.apache.river.impl.util.CollectionsConcurrent;

/**
* This homogenous PermissionCollection is designed to overcome some
shortfalls with existing
* PermissionCollection's that block for potentially long durations
* on implies(), like SocketPermissionCollection.
*
* @author peter
*/
final class DynamicPermissionCollection extends PermissionCollection {
  private static final long serialVersionUID = 1L;
     private final Collection<Permission> perms;
  private final Class cl;
  private final Comparator<Permission> comp;
     DynamicPermissionCollection(Comparator<Permission> c, Class cl){
      perms = CollectionsConcurrent.multiReadCollection(new
ArrayList<Permission>());
      this.cl = cl;
      comp = c;
  }
     private DynamicPermissionCollection(Class cl, Comparator<Permission>
c){
      this.cl = cl;
      comp = c;
      Collection<Permission> col = new ArrayList<Permission>();
      perms = CollectionsConcurrent.multiReadCollection(col);
  }

  @Override
  public void add(Permission permission) {
      if ( ! cl.isInstance(permission))
          throw new IllegalArgumentException("invalid permission: "+
permission);
      if (isReadOnly()) throw new SecurityException("PermissionCollection is
read only");
      perms.add(permission);
  }

  @Override
  public boolean implies(Permission permission) {
      if ( ! cl.isInstance(permission)) return false;
      Permission [] p = perms.toArray(new Permission[0]); //perms.size() may
change
      if (comp != null){
          Arrays.sort(p, comp);
      }
      PermissionCollection pc = permission.newPermissionCollection();
      int l = p.length;
      if (pc != null) {
          for ( int i = 0; i < l ; i++ ){
              pc.add(p[i]);
          }
          return pc.implies(permission);
      }
      for ( int i = 0; i < l ; i++ ){
          if (p[i].implies(permission)) return true;
      }
      return false;
  }

  @Override
  public Enumeration<Permission> elements() {
      return Collections.enumeration(perms);
  }
     private Collection<Permission> getPermissions(){
      return perms;
  }
     private void readObject(ObjectInputStream stream) throws
              InvalidObjectException, IOException, ClassNotFoundException {
          throw new InvalidObjectException("Serialization Proxy required");
  }
     private Object writeReplace(){
          PermissionCollection pc =
              new SerializationProxy(cl, comp, this);
          if (isReadOnly()) pc.setReadOnly();
          return pc;
  }
     /**
   * A serialization proxy has been provided to allow the fields in
DynamicPermissionCollection
   * to be final.
   *
   * The serialization proxy extends PermissionCollection for cases where
   * it may contain a Permission that refers to it, eg a DelegatePermission.
   * To fix the readResolve bug.
   *
   * This has been provided to implement Serialization, it is better to
   * avoid serializing a PermissionCollection.
   */
  private final static class SerializationProxy extends PermissionCollection
{
      private static final long serialVersionUID = 1L;
      private Permission[] permissions;
      private Class clazz;
      private Comparator<Permission> comp;
      private transient DynamicPermissionCollection resolved;
      SerializationProxy(Class cl, Comparator<Permission> c,
DynamicPermissionCollection pc){
          permissions = null;
          clazz = cl;
          comp = c;
          resolved = pc;
      }
             private Object readResolve() {
          PermissionCollection pc =
                  new DynamicPermissionCollection(clazz, comp);
          int length = permissions.length;
          for ( int i = 0 ; i < length ; i++){
              pc.add(permissions[i]);
          }
          if (isReadOnly()) pc.setReadOnly();
          return pc;
      }
             private void writeObject(ObjectOutputStream s) throws
IOException{
          permissions = resolved.getPermissions().toArray(new
Permission[0]);
          s.defaultWriteObject();
      }
             private void readObject(ObjectInputStream stream) throws
              InvalidObjectException, IOException, ClassNotFoundException {
          stream.defaultReadObject();
      }

      @Override
      public void add(Permission permission) {
          if ( resolved != null ){
              resolved.add(permission);
              return;
          }
          throw new IllegalStateException("unresolved after serialization");
      }

      @Override
      public boolean implies(Permission permission) {
          if ( resolved != null ){
              return resolved.implies(permission);
          }
          throw new IllegalStateException("unresolved after serialization");
      }

      @Override
      public Enumeration<Permission> elements() {
          if ( resolved != null ){
              return resolved.elements();
          }
          throw new IllegalStateException("unresolved after serialization");
      }
             @Override
      public void setReadOnly(){
          super.setReadOnly();
          resolved.setReadOnly();
      }
      }

}



Reply via email to