1. /*
  2. * @(#)PresentationManagerImpl.java 1.13 04/06/21
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package com.sun.corba.se.impl.presentation.rmi ;
  8. import java.util.Map ;
  9. import java.util.HashMap ;
  10. import java.util.Set ;
  11. import java.util.HashSet ;
  12. import java.util.List ;
  13. import java.util.ArrayList ;
  14. import java.util.Iterator ;
  15. import java.lang.reflect.Method ;
  16. import java.rmi.Remote ;
  17. import javax.rmi.CORBA.Tie ;
  18. import com.sun.corba.se.spi.orbutil.proxy.InvocationHandlerFactory ;
  19. import com.sun.corba.se.spi.presentation.rmi.IDLNameTranslator ;
  20. import com.sun.corba.se.spi.presentation.rmi.DynamicMethodMarshaller ;
  21. import com.sun.corba.se.spi.presentation.rmi.PresentationManager ;
  22. import com.sun.corba.se.spi.logging.CORBALogDomains ;
  23. import com.sun.corba.se.impl.logging.ORBUtilSystemException ;
  24. import com.sun.corba.se.impl.presentation.rmi.IDLNameTranslatorImpl ;
  25. import com.sun.corba.se.impl.presentation.rmi.StubFactoryProxyImpl ;
  26. import com.sun.corba.se.impl.orbutil.graph.Node ;
  27. import com.sun.corba.se.impl.orbutil.graph.Graph ;
  28. import com.sun.corba.se.impl.orbutil.graph.GraphImpl ;
  29. public final class PresentationManagerImpl implements PresentationManager
  30. {
  31. private Map classToClassData ;
  32. private Map methodToDMM ;
  33. private PresentationManager.StubFactoryFactory staticStubFactoryFactory ;
  34. private PresentationManager.StubFactoryFactory dynamicStubFactoryFactory ;
  35. private ORBUtilSystemException wrapper = null ;
  36. private boolean useDynamicStubs ;
  37. public PresentationManagerImpl( boolean useDynamicStubs )
  38. {
  39. this.useDynamicStubs = useDynamicStubs ;
  40. wrapper = ORBUtilSystemException.get(
  41. CORBALogDomains.RPC_PRESENTATION ) ;
  42. // XXX these should probably be WeakHashMaps.
  43. classToClassData = new HashMap() ;
  44. methodToDMM = new HashMap() ;
  45. }
  46. ////////////////////////////////////////////////////////////////////////////////
  47. // PresentationManager interface
  48. ////////////////////////////////////////////////////////////////////////////////
  49. public synchronized DynamicMethodMarshaller getDynamicMethodMarshaller(
  50. Method method )
  51. {
  52. if (method == null)
  53. return null ;
  54. DynamicMethodMarshaller result =
  55. (DynamicMethodMarshaller)methodToDMM.get( method ) ;
  56. if (result == null) {
  57. result = new DynamicMethodMarshallerImpl( method ) ;
  58. methodToDMM.put( method, result ) ;
  59. }
  60. return result ;
  61. }
  62. public synchronized ClassData getClassData( Class cls )
  63. {
  64. ClassData result = (ClassData)classToClassData.get( cls ) ;
  65. if (result == null) {
  66. result = new ClassDataImpl( cls ) ;
  67. classToClassData.put( cls, result ) ;
  68. }
  69. return result ;
  70. }
  71. private class ClassDataImpl implements PresentationManager.ClassData
  72. {
  73. private Class cls ;
  74. private IDLNameTranslator nameTranslator ;
  75. private String[] typeIds ;
  76. private PresentationManager.StubFactory sfactory ;
  77. private InvocationHandlerFactory ihfactory ;
  78. private Map dictionary ;
  79. public ClassDataImpl( Class cls )
  80. {
  81. this.cls = cls ;
  82. Graph gr = new GraphImpl() ;
  83. NodeImpl root = new NodeImpl( cls ) ;
  84. Set rootSet = getRootSet( cls, root, gr ) ;
  85. // At this point, rootSet contains those remote interfaces
  86. // that are not related by inheritance, and gr contains
  87. // all reachable remote interfaces.
  88. Class[] interfaces = getInterfaces( rootSet ) ;
  89. nameTranslator = IDLNameTranslatorImpl.get( interfaces ) ;
  90. typeIds = makeTypeIds( root, gr, rootSet ) ;
  91. ihfactory = new InvocationHandlerFactoryImpl(
  92. PresentationManagerImpl.this, this ) ;
  93. dictionary = new HashMap() ;
  94. }
  95. public Class getMyClass()
  96. {
  97. return cls ;
  98. }
  99. public IDLNameTranslator getIDLNameTranslator()
  100. {
  101. return nameTranslator ;
  102. }
  103. public String[] getTypeIds()
  104. {
  105. return typeIds ;
  106. }
  107. public InvocationHandlerFactory getInvocationHandlerFactory()
  108. {
  109. return ihfactory ;
  110. }
  111. public Map getDictionary()
  112. {
  113. return dictionary ;
  114. }
  115. }
  116. public PresentationManager.StubFactoryFactory getStubFactoryFactory(
  117. boolean isDynamic )
  118. {
  119. if (isDynamic)
  120. return dynamicStubFactoryFactory ;
  121. else
  122. return staticStubFactoryFactory ;
  123. }
  124. public void setStubFactoryFactory( boolean isDynamic,
  125. PresentationManager.StubFactoryFactory sff )
  126. {
  127. if (isDynamic)
  128. dynamicStubFactoryFactory = sff ;
  129. else
  130. staticStubFactoryFactory = sff ;
  131. }
  132. public Tie getTie()
  133. {
  134. return dynamicStubFactoryFactory.getTie( null ) ;
  135. }
  136. public boolean useDynamicStubs()
  137. {
  138. return useDynamicStubs ;
  139. }
  140. ////////////////////////////////////////////////////////////////////////////////
  141. // Graph computations
  142. ////////////////////////////////////////////////////////////////////////////////
  143. private Set getRootSet( Class target, NodeImpl root, Graph gr )
  144. {
  145. Set rootSet = null ;
  146. if (target.isInterface()) {
  147. gr.add( root ) ;
  148. rootSet = gr.getRoots() ; // rootSet just contains root here
  149. } else {
  150. // Use this class and its superclasses (not Object) as initial roots
  151. Class superclass = target ;
  152. Set initialRootSet = new HashSet() ;
  153. while ((superclass != null) && !superclass.equals( Object.class )) {
  154. Node node = new NodeImpl( superclass ) ;
  155. gr.add( node ) ;
  156. initialRootSet.add( node ) ;
  157. superclass = superclass.getSuperclass() ;
  158. }
  159. // Expand all nodes into the graph
  160. gr.getRoots() ;
  161. // remove the roots and find roots again
  162. gr.removeAll( initialRootSet ) ;
  163. rootSet = gr.getRoots() ;
  164. }
  165. return rootSet ;
  166. }
  167. private Class[] getInterfaces( Set roots )
  168. {
  169. Class[] classes = new Class[ roots.size() ] ;
  170. Iterator iter = roots.iterator() ;
  171. int ctr = 0 ;
  172. while (iter.hasNext()) {
  173. NodeImpl node = (NodeImpl)iter.next() ;
  174. classes[ctr++] = node.getInterface() ;
  175. }
  176. return classes ;
  177. }
  178. private String[] makeTypeIds( NodeImpl root, Graph gr, Set rootSet )
  179. {
  180. Set nonRootSet = new HashSet( gr ) ;
  181. nonRootSet.removeAll( rootSet ) ;
  182. // List<String> for the typeids
  183. List result = new ArrayList() ;
  184. if (rootSet.size() > 1) {
  185. // If the rootSet has more than one element, we must
  186. // put the type id of the implementation class first.
  187. // Root represents the implementation class here.
  188. result.add( root.getTypeId() ) ;
  189. }
  190. addNodes( result, rootSet ) ;
  191. addNodes( result, nonRootSet ) ;
  192. return (String[])result.toArray( new String[result.size()] ) ;
  193. }
  194. private void addNodes( List resultList, Set nodeSet )
  195. {
  196. Iterator iter = nodeSet.iterator() ;
  197. while (iter.hasNext()) {
  198. NodeImpl node = (NodeImpl)iter.next() ;
  199. String typeId = node.getTypeId() ;
  200. resultList.add( typeId ) ;
  201. }
  202. }
  203. private static class NodeImpl implements Node
  204. {
  205. private Class interf ;
  206. public Class getInterface()
  207. {
  208. return interf ;
  209. }
  210. public NodeImpl( Class interf )
  211. {
  212. this.interf = interf ;
  213. }
  214. public String getTypeId()
  215. {
  216. return "RMI:" + interf.getName() + ":0000000000000000" ;
  217. }
  218. public Set getChildren()
  219. {
  220. Set result = new HashSet() ;
  221. Class[] interfaces = interf.getInterfaces() ;
  222. for (int ctr=0; ctr<interfaces.length; ctr++) {
  223. Class cls = interfaces[ctr] ;
  224. if (Remote.class.isAssignableFrom(cls) &&
  225. !Remote.class.equals(cls))
  226. result.add( new NodeImpl( cls ) ) ;
  227. }
  228. return result ;
  229. }
  230. public String toString()
  231. {
  232. return "NodeImpl[" + interf + "]" ;
  233. }
  234. public int hashCode()
  235. {
  236. return interf.hashCode() ;
  237. }
  238. public boolean equals( Object obj )
  239. {
  240. if (this == obj)
  241. return true ;
  242. if (!(obj instanceof NodeImpl))
  243. return false ;
  244. NodeImpl other = (NodeImpl)obj ;
  245. return other.interf.equals( interf ) ;
  246. }
  247. }
  248. }