1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 package com.sun.star.uno; 25 26 import com.sun.star.uno.XWeak; 27 import com.sun.star.uno.UnoRuntime; 28 import com.sun.star.uno.XAdapter; 29 import com.sun.star.uno.XReference; 30 31 /** This class holds weak reference to an object. It actually holds a reference to a 32 com.sun.star.XAdapter implementation and obtains a hard reference if necessary. 33 */ 34 public class WeakReference 35 { 36 private final boolean DEBUG= false; 37 private OWeakRefListener m_listener; 38 // There is no default constructor. Every instance must register itself with the 39 // XAdapter interface, which is done in the constructors. Assume we have this code 40 // WeakReference ref= new WeakReference(); 41 // ref = someOtherWeakReference; 42 // 43 // ref would not be notified (XReference.dispose()) because it did not register 44 // itself. Therefore the XAdapter would be kept aliver although this is not 45 // necessary. 46 47 /** Creates an instance of this class. 48 *@param obj - another instance that is to be copied 49 */ WeakReference(WeakReference obj)50 public WeakReference(WeakReference obj) 51 { 52 if (obj != null) 53 { 54 Object weakImpl= obj.get(); 55 if (weakImpl != null) 56 { 57 XWeak weak= UnoRuntime.queryInterface(XWeak.class, weakImpl); 58 if (weak != null) 59 { 60 XAdapter adapter= (XAdapter) weak.queryAdapter(); 61 if (adapter != null) 62 m_listener= new OWeakRefListener(adapter); 63 } 64 } 65 } 66 } 67 68 /** Creates an instance of this class. 69 *@param obj XWeak implementation 70 */ WeakReference(Object obj)71 public WeakReference(Object obj) 72 { 73 XWeak weak= UnoRuntime.queryInterface(XWeak.class, obj); 74 if (weak != null) 75 { 76 XAdapter adapter= (XAdapter) weak.queryAdapter(); 77 if (adapter != null) 78 m_listener= new OWeakRefListener(adapter); 79 } 80 } 81 /** Returns a hard reference to the object that is kept weak by this class. 82 *@return a hard reference to the XWeak implementation. 83 */ get()84 public Object get() 85 { 86 if (m_listener != null) 87 return m_listener.get(); 88 return null; 89 } 90 } 91 92 /** Implementation of com.sun.star.uno.XReference for use with WeakReference. 93 * It keeps the XAdapter implementation and registers always with it. Deregistering 94 * occurs on notification by the adapter and the adapter is released. 95 */ 96 class OWeakRefListener implements XReference 97 { 98 private final boolean DEBUG= false; 99 private XAdapter m_adapter; 100 101 /** The constructor registered this object with adapter. 102 *@param adapter the XAdapter implementation. 103 */ OWeakRefListener( XAdapter adapter)104 OWeakRefListener( XAdapter adapter) 105 { 106 m_adapter= adapter; 107 m_adapter.addReference(this); 108 } 109 /** Method of com.sun.star.uno.XReference. When called, it deregisteres this 110 * object with the adapter and releases the reference to it. 111 */ dispose()112 synchronized public void dispose() 113 { 114 if (m_adapter != null) 115 { 116 m_adapter.removeReference(this); 117 m_adapter= null; 118 } 119 } 120 121 /** Obtains a hard reference to the object which is kept weak by the adapter 122 * and returns it. 123 * @return hard reference to the otherwise weakly kept object. 124 */ get()125 synchronized Object get() 126 { 127 Object retVal= null; 128 if (m_adapter != null) 129 { 130 retVal= m_adapter.queryAdapted(); 131 if (retVal == null) 132 { 133 // If this object registered as listener with XAdapter while it was notifying 134 // the listeners then this object might not have been notified. If queryAdapted 135 // returned null then the weak kept object is dead and the listeners have already 136 // been notified. And we missed it. 137 m_adapter.removeReference(this); 138 m_adapter= null; 139 } 140 } 141 return retVal; 142 } 143 } 144