- /*
- * @(#)InterceptorList.java 1.16 03/01/23
- *
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- */
-
- package com.sun.corba.se.internal.Interceptors;
-
- import org.omg.PortableInterceptor.Interceptor;
- import org.omg.PortableInterceptor.ORBInitInfo;
- import org.omg.PortableInterceptor.ORBInitInfoPackage.DuplicateName;
-
- import org.omg.CORBA.INTERNAL;
-
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.Collections;
- import java.util.Iterator;
- import java.util.List;
- import java.lang.reflect.Array;
-
- /**
- * Provides a repository of registered Portable Interceptors, organized
- * by type. This list is designed to be accessed as efficiently as
- * possible during runtime, with the expense of added complexity during
- * initialization and interceptor registration. The class is designed
- * to easily allow for the addition of new interceptor types.
- */
- public class InterceptorList {
-
- // Interceptor type list. If additional interceptors are needed,
- // add additional types in numerical order (do not skip numbers),
- // and update NUM_INTERCEPTOR_TYPES and classTypes accordingly.
- // NUM_INTERCEPTOR_TYPES represents the number of interceptor
- // types, so we know how many lists to maintain.
- static final int INTERCEPTOR_TYPE_CLIENT = 0;
- static final int INTERCEPTOR_TYPE_SERVER = 1;
- static final int INTERCEPTOR_TYPE_IOR = 2;
-
- static final int NUM_INTERCEPTOR_TYPES = 3;
-
- // Array of class types for interceptors. This is used to create the
- // appropriate array type for each interceptor type. These must
- // match the indices of the constants declared above.
- static final Class[] classTypes = {
- org.omg.PortableInterceptor.ClientRequestInterceptor.class,
- org.omg.PortableInterceptor.ServerRequestInterceptor.class,
- org.omg.PortableInterceptor.IORInterceptor.class
- };
-
- // True if no further interceptors may be registered with this list.
- private boolean locked = false;
-
- // List of interceptors currently registered. There are
- // NUM_INTERCEPTOR_TYPES lists of registered interceptors.
- // For example, interceptors[INTERCEPTOR_TYPE_CLIENT] contains an array
- // of objects of type ClientRequestInterceptor.
- private Interceptor[][] interceptors =
- new Interceptor[NUM_INTERCEPTOR_TYPES][];
-
- /**
- * Creates a new Interceptor List. Constructor is package scope so
- * only the ORB can create it.
- */
- InterceptorList() {
- // Create empty interceptors arrays for each type:
- initInterceptorArrays();
- }
-
- /**
- * Registers an interceptor of the given type into the interceptor list.
- * The type is one of:
- * <ul>
- * <li>INTERCEPTOR_TYPE_CLIENT - ClientRequestInterceptor
- * <li>INTERCEPTOR_TYPE_SERVER - ServerRequestInterceptor
- * <li>INTERCEPTOR_TYPE_IOR - IORInterceptor
- * </ul>
- *
- * @exception DuplicateName Thrown if an interceptor of the given
- * name already exists for the given type.
- */
- void register_interceptor( Interceptor interceptor, int type )
- throws DuplicateName
- {
- // If locked, deny any further addition of interceptors.
- if( locked ) {
- throw new INTERNAL( "InterceptorList is locked." );
- }
-
- // Cache interceptor name:
- String interceptorName = interceptor.name();
- boolean anonymous = interceptorName.equals( "" );
- boolean foundDuplicate = false;
- Interceptor[] interceptorList = interceptors[type];
-
- // If this is not an anonymous interceptor,
- // search for an interceptor of the same name in this category:
- if( !anonymous ) {
- int size = interceptorList.length;
-
- // An O(n) search will suffice because register_interceptor is not
- // likely to be called often.
- for( int i = 0; i < size; i++ ) {
- Interceptor in = (Interceptor)interceptorList[i];
- if( in.name().equals( interceptorName ) ) {
- foundDuplicate = true;
- break;
- }
- }
- }
-
- if( !foundDuplicate ) {
- growInterceptorArray( type );
- interceptors[type][interceptors[type].length-1] = interceptor;
- }
- else {
- throw new DuplicateName( interceptorName );
- }
- }
-
- /**
- * Locks this interceptor list so that no more interceptors may be
- * registered. This method is called after all interceptors are
- * registered for security reasons.
- */
- void lock() {
- locked = true;
- }
-
- /**
- * Retrieves an array of interceptors of the given type. For efficiency,
- * the type parameter is assumed to be valid.
- */
- Interceptor[] getInterceptors( int type ) {
- return interceptors[type];
- }
-
- /**
- * Returns true if there is at least one interceptor of the given type,
- * or false if not.
- */
- boolean hasInterceptorsOfType( int type ) {
- return interceptors[type].length > 0;
- }
-
- /**
- * Initializes all interceptors arrays to zero-length arrays of the
- * correct type, based on the classTypes list.
- */
- private void initInterceptorArrays() {
- for( int type = 0; type < NUM_INTERCEPTOR_TYPES; type++ ) {
- Class classType = classTypes[type];
-
- // Create a zero-length array for each type:
- interceptors[type] =
- (Interceptor[])Array.newInstance( classType, 0 );
- }
- }
-
- /**
- * Grows the given interceptor array by one:
- */
- private void growInterceptorArray( int type ) {
- Class classType = classTypes[type];
- int currentLength = interceptors[type].length;
- Interceptor[] replacementArray;
-
- // Create new array to replace the old one. The new array will be
- // one element larger but have the same type as the old one.
- replacementArray = (Interceptor[])
- Array.newInstance( classType, currentLength + 1 );
- System.arraycopy( interceptors[type], 0,
- replacementArray, 0, currentLength );
- interceptors[type] = replacementArray;
- }
-
- /**
- * Destroys all interceptors in this list by invoking their destroy()
- * method.
- */
- void destroyAll() {
- int numTypes = interceptors.length;
-
- for( int i = 0; i < numTypes; i++ ) {
- int numInterceptors = interceptors[i].length;
- for( int j = 0; j < numInterceptors; j++ ) {
- interceptors[i][j].destroy();
- }
- }
- }
-
- /**
- * Sort interceptors.
- */
- void sortInterceptors() {
- List sorted = null;
- List unsorted = null;
-
- int numTypes = interceptors.length;
-
- for( int i = 0; i < numTypes; i++ ) {
- int numInterceptors = interceptors[i].length;
- if (numInterceptors > 0) {
- // Get fresh sorting bins for each non empty type.
- sorted = new ArrayList(); // not synchronized like we want.
- unsorted = new ArrayList();
- }
- for( int j = 0; j < numInterceptors; j++ ) {
- Interceptor interceptor = interceptors[i][j];
- if (interceptor instanceof Comparable) {
- sorted.add(interceptor);
- } else {
- unsorted.add(interceptor);
- }
- }
- if (numInterceptors > 0 && sorted.size() > 0) {
- // Let the RuntimeExceptions thrown by sort
- // (i.e., ClassCastException and UnsupportedOperationException)
- // flow back to the user.
- Collections.sort(sorted);
- Iterator sortedIterator = sorted.iterator();
- Iterator unsortedIterator = unsorted.iterator();
- for( int j = 0; j < numInterceptors; j++ ) {
- if (sortedIterator.hasNext()) {
- interceptors[i][j] =
- (Interceptor) sortedIterator.next();
- } else if (unsortedIterator.hasNext()) {
- interceptors[i][j] =
- (Interceptor) unsortedIterator.next();
- } else {
- throw new INTERNAL("InterceptorList.sortInterceptors");
- }
- }
- }
- }
- }
-
- }
-