PresentationManagerImpl.java revision 608:7e06bf1dcb09
1/* 2 * Copyright (c) 2003, 2004, 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.presentation.rmi ; 27 28import java.util.Map ; 29import java.util.HashMap ; 30import java.util.Set ; 31import java.util.HashSet ; 32import java.util.List ; 33import java.util.ArrayList ; 34import java.util.Iterator ; 35 36import java.lang.reflect.Method ; 37 38import java.rmi.Remote ; 39 40import javax.rmi.CORBA.Tie ; 41 42import com.sun.corba.se.spi.orbutil.proxy.InvocationHandlerFactory ; 43 44import com.sun.corba.se.spi.presentation.rmi.IDLNameTranslator ; 45import com.sun.corba.se.spi.presentation.rmi.DynamicMethodMarshaller ; 46import com.sun.corba.se.spi.presentation.rmi.PresentationManager ; 47 48import com.sun.corba.se.spi.logging.CORBALogDomains ; 49 50import com.sun.corba.se.impl.logging.ORBUtilSystemException ; 51 52import com.sun.corba.se.impl.presentation.rmi.IDLNameTranslatorImpl ; 53import com.sun.corba.se.impl.presentation.rmi.StubFactoryProxyImpl ; 54 55import com.sun.corba.se.impl.orbutil.graph.Node ; 56import com.sun.corba.se.impl.orbutil.graph.Graph ; 57import com.sun.corba.se.impl.orbutil.graph.GraphImpl ; 58 59public final class PresentationManagerImpl implements PresentationManager 60{ 61 private Map classToClassData ; 62 private Map methodToDMM ; 63 private PresentationManager.StubFactoryFactory staticStubFactoryFactory ; 64 private PresentationManager.StubFactoryFactory dynamicStubFactoryFactory ; 65 private ORBUtilSystemException wrapper = null ; 66 private boolean useDynamicStubs ; 67 68 public PresentationManagerImpl( boolean useDynamicStubs ) 69 { 70 this.useDynamicStubs = useDynamicStubs ; 71 wrapper = ORBUtilSystemException.get( 72 CORBALogDomains.RPC_PRESENTATION ) ; 73 74 // XXX these should probably be WeakHashMaps. 75 classToClassData = new HashMap() ; 76 methodToDMM = new HashMap() ; 77 } 78 79//////////////////////////////////////////////////////////////////////////////// 80// PresentationManager interface 81//////////////////////////////////////////////////////////////////////////////// 82 83 public synchronized DynamicMethodMarshaller getDynamicMethodMarshaller( 84 Method method ) 85 { 86 if (method == null) 87 return null ; 88 89 DynamicMethodMarshaller result = 90 (DynamicMethodMarshaller)methodToDMM.get( method ) ; 91 if (result == null) { 92 result = new DynamicMethodMarshallerImpl( method ) ; 93 methodToDMM.put( method, result ) ; 94 } 95 96 return result ; 97 } 98 99 public synchronized ClassData getClassData( Class cls ) 100 { 101 ClassData result = (ClassData)classToClassData.get( cls ) ; 102 if (result == null) { 103 result = new ClassDataImpl( cls ) ; 104 classToClassData.put( cls, result ) ; 105 } 106 107 return result ; 108 } 109 110 private class ClassDataImpl implements PresentationManager.ClassData 111 { 112 private Class cls ; 113 private IDLNameTranslator nameTranslator ; 114 private String[] typeIds ; 115 private PresentationManager.StubFactory sfactory ; 116 private InvocationHandlerFactory ihfactory ; 117 private Map dictionary ; 118 119 public ClassDataImpl( Class cls ) 120 { 121 this.cls = cls ; 122 Graph gr = new GraphImpl() ; 123 NodeImpl root = new NodeImpl( cls ) ; 124 Set rootSet = getRootSet( cls, root, gr ) ; 125 126 // At this point, rootSet contains those remote interfaces 127 // that are not related by inheritance, and gr contains 128 // all reachable remote interfaces. 129 130 Class[] interfaces = getInterfaces( rootSet ) ; 131 nameTranslator = IDLNameTranslatorImpl.get( interfaces ) ; 132 typeIds = makeTypeIds( root, gr, rootSet ) ; 133 ihfactory = new InvocationHandlerFactoryImpl( 134 PresentationManagerImpl.this, this ) ; 135 dictionary = new HashMap() ; 136 } 137 138 public Class getMyClass() 139 { 140 return cls ; 141 } 142 143 public IDLNameTranslator getIDLNameTranslator() 144 { 145 return nameTranslator ; 146 } 147 148 public String[] getTypeIds() 149 { 150 return typeIds ; 151 } 152 153 public InvocationHandlerFactory getInvocationHandlerFactory() 154 { 155 return ihfactory ; 156 } 157 158 public Map getDictionary() 159 { 160 return dictionary ; 161 } 162 } 163 164 public PresentationManager.StubFactoryFactory getStubFactoryFactory( 165 boolean isDynamic ) 166 { 167 if (isDynamic) 168 return dynamicStubFactoryFactory ; 169 else 170 return staticStubFactoryFactory ; 171 } 172 173 public void setStubFactoryFactory( boolean isDynamic, 174 PresentationManager.StubFactoryFactory sff ) 175 { 176 if (isDynamic) 177 dynamicStubFactoryFactory = sff ; 178 else 179 staticStubFactoryFactory = sff ; 180 } 181 182 public Tie getTie() 183 { 184 return dynamicStubFactoryFactory.getTie( null ) ; 185 } 186 187 public boolean useDynamicStubs() 188 { 189 return useDynamicStubs ; 190 } 191 192//////////////////////////////////////////////////////////////////////////////// 193// Graph computations 194//////////////////////////////////////////////////////////////////////////////// 195 196 private Set getRootSet( Class target, NodeImpl root, Graph gr ) 197 { 198 Set rootSet = null ; 199 200 if (target.isInterface()) { 201 gr.add( root ) ; 202 rootSet = gr.getRoots() ; // rootSet just contains root here 203 } else { 204 // Use this class and its superclasses (not Object) as initial roots 205 Class superclass = target ; 206 Set initialRootSet = new HashSet() ; 207 while ((superclass != null) && !superclass.equals( Object.class )) { 208 Node node = new NodeImpl( superclass ) ; 209 gr.add( node ) ; 210 initialRootSet.add( node ) ; 211 superclass = superclass.getSuperclass() ; 212 } 213 214 // Expand all nodes into the graph 215 gr.getRoots() ; 216 217 // remove the roots and find roots again 218 gr.removeAll( initialRootSet ) ; 219 rootSet = gr.getRoots() ; 220 } 221 222 return rootSet ; 223 } 224 225 private Class[] getInterfaces( Set roots ) 226 { 227 Class[] classes = new Class[ roots.size() ] ; 228 Iterator iter = roots.iterator() ; 229 int ctr = 0 ; 230 while (iter.hasNext()) { 231 NodeImpl node = (NodeImpl)iter.next() ; 232 classes[ctr++] = node.getInterface() ; 233 } 234 235 return classes ; 236 } 237 238 private String[] makeTypeIds( NodeImpl root, Graph gr, Set rootSet ) 239 { 240 Set nonRootSet = new HashSet( gr ) ; 241 nonRootSet.removeAll( rootSet ) ; 242 243 // List<String> for the typeids 244 List result = new ArrayList() ; 245 246 if (rootSet.size() > 1) { 247 // If the rootSet has more than one element, we must 248 // put the type id of the implementation class first. 249 // Root represents the implementation class here. 250 result.add( root.getTypeId() ) ; 251 } 252 253 addNodes( result, rootSet ) ; 254 addNodes( result, nonRootSet ) ; 255 256 return (String[])result.toArray( new String[result.size()] ) ; 257 } 258 259 private void addNodes( List resultList, Set nodeSet ) 260 { 261 Iterator iter = nodeSet.iterator() ; 262 while (iter.hasNext()) { 263 NodeImpl node = (NodeImpl)iter.next() ; 264 String typeId = node.getTypeId() ; 265 resultList.add( typeId ) ; 266 } 267 } 268 269 private static class NodeImpl implements Node 270 { 271 private Class interf ; 272 273 public Class getInterface() 274 { 275 return interf ; 276 } 277 278 public NodeImpl( Class interf ) 279 { 280 this.interf = interf ; 281 } 282 283 public String getTypeId() 284 { 285 return "RMI:" + interf.getName() + ":0000000000000000" ; 286 } 287 288 public Set getChildren() 289 { 290 Set result = new HashSet() ; 291 Class[] interfaces = interf.getInterfaces() ; 292 for (int ctr=0; ctr<interfaces.length; ctr++) { 293 Class cls = interfaces[ctr] ; 294 if (Remote.class.isAssignableFrom(cls) && 295 !Remote.class.equals(cls)) 296 result.add( new NodeImpl( cls ) ) ; 297 } 298 299 return result ; 300 } 301 302 public String toString() 303 { 304 return "NodeImpl[" + interf + "]" ; 305 } 306 307 public int hashCode() 308 { 309 return interf.hashCode() ; 310 } 311 312 public boolean equals( Object obj ) 313 { 314 if (this == obj) 315 return true ; 316 317 if (!(obj instanceof NodeImpl)) 318 return false ; 319 320 NodeImpl other = (NodeImpl)obj ; 321 322 return other.interf.equals( interf ) ; 323 } 324 } 325} 326