InterceptorList.java revision 608:7e06bf1dcb09
1281760Ssjg/* 2281760Ssjg * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package com.sun.corba.se.impl.interceptors; 27 28import org.omg.PortableInterceptor.Interceptor; 29import org.omg.PortableInterceptor.ORBInitInfo; 30import org.omg.PortableInterceptor.ORBInitInfoPackage.DuplicateName; 31 32import org.omg.CORBA.INTERNAL; 33 34import java.util.ArrayList; 35import java.util.Collection; 36import java.util.Collections; 37import java.util.Iterator; 38import java.util.List; 39import java.lang.reflect.Array; 40 41import com.sun.corba.se.impl.logging.InterceptorsSystemException ; 42 43/** 44 * Provides a repository of registered Portable Interceptors, organized 45 * by type. This list is designed to be accessed as efficiently as 46 * possible during runtime, with the expense of added complexity during 47 * initialization and interceptor registration. The class is designed 48 * to easily allow for the addition of new interceptor types. 49 */ 50public class InterceptorList { 51 52 // Interceptor type list. If additional interceptors are needed, 53 // add additional types in numerical order (do not skip numbers), 54 // and update NUM_INTERCEPTOR_TYPES and classTypes accordingly. 55 // NUM_INTERCEPTOR_TYPES represents the number of interceptor 56 // types, so we know how many lists to maintain. 57 static final int INTERCEPTOR_TYPE_CLIENT = 0; 58 static final int INTERCEPTOR_TYPE_SERVER = 1; 59 static final int INTERCEPTOR_TYPE_IOR = 2; 60 61 static final int NUM_INTERCEPTOR_TYPES = 3; 62 63 // Array of class types for interceptors. This is used to create the 64 // appropriate array type for each interceptor type. These must 65 // match the indices of the constants declared above. 66 static final Class[] classTypes = { 67 org.omg.PortableInterceptor.ClientRequestInterceptor.class, 68 org.omg.PortableInterceptor.ServerRequestInterceptor.class, 69 org.omg.PortableInterceptor.IORInterceptor.class 70 }; 71 72 // True if no further interceptors may be registered with this list. 73 private boolean locked = false; 74 private InterceptorsSystemException wrapper ; 75 76 // List of interceptors currently registered. There are 77 // NUM_INTERCEPTOR_TYPES lists of registered interceptors. 78 // For example, interceptors[INTERCEPTOR_TYPE_CLIENT] contains an array 79 // of objects of type ClientRequestInterceptor. 80 private Interceptor[][] interceptors = 81 new Interceptor[NUM_INTERCEPTOR_TYPES][]; 82 83 /** 84 * Creates a new Interceptor List. Constructor is package scope so 85 * only the ORB can create it. 86 */ 87 InterceptorList( InterceptorsSystemException wrapper ) { 88 this.wrapper = wrapper ; 89 // Create empty interceptors arrays for each type: 90 initInterceptorArrays(); 91 } 92 93 /** 94 * Registers an interceptor of the given type into the interceptor list. 95 * The type is one of: 96 * <ul> 97 * <li>INTERCEPTOR_TYPE_CLIENT - ClientRequestInterceptor 98 * <li>INTERCEPTOR_TYPE_SERVER - ServerRequestInterceptor 99 * <li>INTERCEPTOR_TYPE_IOR - IORInterceptor 100 * </ul> 101 * 102 * @exception DuplicateName Thrown if an interceptor of the given 103 * name already exists for the given type. 104 */ 105 void register_interceptor( Interceptor interceptor, int type ) 106 throws DuplicateName 107 { 108 // If locked, deny any further addition of interceptors. 109 if( locked ) { 110 throw wrapper.interceptorListLocked() ; 111 } 112 113 // Cache interceptor name: 114 String interceptorName = interceptor.name(); 115 boolean anonymous = interceptorName.equals( "" ); 116 boolean foundDuplicate = false; 117 Interceptor[] interceptorList = interceptors[type]; 118 119 // If this is not an anonymous interceptor, 120 // search for an interceptor of the same name in this category: 121 if( !anonymous ) { 122 int size = interceptorList.length; 123 124 // An O(n) search will suffice because register_interceptor is not 125 // likely to be called often. 126 for( int i = 0; i < size; i++ ) { 127 Interceptor in = (Interceptor)interceptorList[i]; 128 if( in.name().equals( interceptorName ) ) { 129 foundDuplicate = true; 130 break; 131 } 132 } 133 } 134 135 if( !foundDuplicate ) { 136 growInterceptorArray( type ); 137 interceptors[type][interceptors[type].length-1] = interceptor; 138 } 139 else { 140 throw new DuplicateName( interceptorName ); 141 } 142 } 143 144 /** 145 * Locks this interceptor list so that no more interceptors may be 146 * registered. This method is called after all interceptors are 147 * registered for security reasons. 148 */ 149 void lock() { 150 locked = true; 151 } 152 153 /** 154 * Retrieves an array of interceptors of the given type. For efficiency, 155 * the type parameter is assumed to be valid. 156 */ 157 Interceptor[] getInterceptors( int type ) { 158 return interceptors[type]; 159 } 160 161 /** 162 * Returns true if there is at least one interceptor of the given type, 163 * or false if not. 164 */ 165 boolean hasInterceptorsOfType( int type ) { 166 return interceptors[type].length > 0; 167 } 168 169 /** 170 * Initializes all interceptors arrays to zero-length arrays of the 171 * correct type, based on the classTypes list. 172 */ 173 private void initInterceptorArrays() { 174 for( int type = 0; type < NUM_INTERCEPTOR_TYPES; type++ ) { 175 Class classType = classTypes[type]; 176 177 // Create a zero-length array for each type: 178 interceptors[type] = 179 (Interceptor[])Array.newInstance( classType, 0 ); 180 } 181 } 182 183 /** 184 * Grows the given interceptor array by one: 185 */ 186 private void growInterceptorArray( int type ) { 187 Class classType = classTypes[type]; 188 int currentLength = interceptors[type].length; 189 Interceptor[] replacementArray; 190 191 // Create new array to replace the old one. The new array will be 192 // one element larger but have the same type as the old one. 193 replacementArray = (Interceptor[]) 194 Array.newInstance( classType, currentLength + 1 ); 195 System.arraycopy( interceptors[type], 0, 196 replacementArray, 0, currentLength ); 197 interceptors[type] = replacementArray; 198 } 199 200 /** 201 * Destroys all interceptors in this list by invoking their destroy() 202 * method. 203 */ 204 void destroyAll() { 205 int numTypes = interceptors.length; 206 207 for( int i = 0; i < numTypes; i++ ) { 208 int numInterceptors = interceptors[i].length; 209 for( int j = 0; j < numInterceptors; j++ ) { 210 interceptors[i][j].destroy(); 211 } 212 } 213 } 214 215 /** 216 * Sort interceptors. 217 */ 218 void sortInterceptors() { 219 List sorted = null; 220 List unsorted = null; 221 222 int numTypes = interceptors.length; 223 224 for( int i = 0; i < numTypes; i++ ) { 225 int numInterceptors = interceptors[i].length; 226 if (numInterceptors > 0) { 227 // Get fresh sorting bins for each non empty type. 228 sorted = new ArrayList(); // not synchronized like we want. 229 unsorted = new ArrayList(); 230 } 231 for( int j = 0; j < numInterceptors; j++ ) { 232 Interceptor interceptor = interceptors[i][j]; 233 if (interceptor instanceof Comparable) { 234 sorted.add(interceptor); 235 } else { 236 unsorted.add(interceptor); 237 } 238 } 239 if (numInterceptors > 0 && sorted.size() > 0) { 240 // Let the RuntimeExceptions thrown by sort 241 // (i.e., ClassCastException and UnsupportedOperationException) 242 // flow back to the user. 243 Collections.sort(sorted); 244 Iterator sortedIterator = sorted.iterator(); 245 Iterator unsortedIterator = unsorted.iterator(); 246 for( int j = 0; j < numInterceptors; j++ ) { 247 if (sortedIterator.hasNext()) { 248 interceptors[i][j] = 249 (Interceptor) sortedIterator.next(); 250 } else if (unsortedIterator.hasNext()) { 251 interceptors[i][j] = 252 (Interceptor) unsortedIterator.next(); 253 } else { 254 throw wrapper.sortSizeMismatch() ; 255 } 256 } 257 } 258 } 259 } 260} 261