1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 package com.sun.star.uno; 29 30 import com.sun.star.uno.XWeak; 31 import com.sun.star.uno.UnoRuntime; 32 import com.sun.star.uno.XAdapter; 33 import com.sun.star.uno.XReference; 34 35 /** This class holds weak reference to an object. It actually holds a reference to a 36 com.sun.star.XAdapter implementation and obtains a hard reference if necessary. 37 */ 38 public class WeakReference 39 { 40 private final boolean DEBUG= false; 41 private OWeakRefListener m_listener; 42 // There is no default constructor. Every instance must register itself with the 43 // XAdapter interface, which is done in the constructors. Assume we have this code 44 // WeakReference ref= new WeakReference(); 45 // ref = someOtherWeakReference; 46 // 47 // ref would not be notified (XReference.dispose()) because it did not register 48 // itself. Therefore the XAdapter would be kept aliver although this is not 49 // necessary. 50 51 /** Creates an instance of this class. 52 *@param obj - another instance that is to be copied 53 */ 54 public WeakReference(WeakReference obj) 55 { 56 if (obj != null) 57 { 58 Object weakImpl= obj.get(); 59 if (weakImpl != null) 60 { 61 XWeak weak= UnoRuntime.queryInterface(XWeak.class, weakImpl); 62 if (weak != null) 63 { 64 XAdapter adapter= (XAdapter) weak.queryAdapter(); 65 if (adapter != null) 66 m_listener= new OWeakRefListener(adapter); 67 } 68 } 69 } 70 } 71 72 /** Creates an instance of this class. 73 *@param obj XWeak implementation 74 */ 75 public WeakReference(Object obj) 76 { 77 XWeak weak= UnoRuntime.queryInterface(XWeak.class, obj); 78 if (weak != null) 79 { 80 XAdapter adapter= (XAdapter) weak.queryAdapter(); 81 if (adapter != null) 82 m_listener= new OWeakRefListener(adapter); 83 } 84 } 85 /** Returns a hard reference to the object that is kept weak by this class. 86 *@return a hard reference to the XWeak implementation. 87 */ 88 public Object get() 89 { 90 if (m_listener != null) 91 return m_listener.get(); 92 return null; 93 } 94 } 95 96 /** Implementation of com.sun.star.uno.XReference for use with WeakReference. 97 * It keeps the XAdapter implementation and registers always with it. Deregistering 98 * occurs on notification by the adapter and the adapter is released. 99 */ 100 class OWeakRefListener implements XReference 101 { 102 private final boolean DEBUG= false; 103 private XAdapter m_adapter; 104 105 /** The constructor registered this object with adapter. 106 *@param adapter the XAdapter implementation. 107 */ 108 OWeakRefListener( XAdapter adapter) 109 { 110 m_adapter= adapter; 111 m_adapter.addReference(this); 112 } 113 /** Method of com.sun.star.uno.XReference. When called, it deregisteres this 114 * object with the adapter and releases the reference to it. 115 */ 116 synchronized public void dispose() 117 { 118 if (m_adapter != null) 119 { 120 m_adapter.removeReference(this); 121 m_adapter= null; 122 } 123 } 124 125 /** Obtains a hard reference to the object which is kept weak by the adapter 126 * and returns it. 127 * @return hard reference to the otherwise weakly kept object. 128 */ 129 synchronized Object get() 130 { 131 Object retVal= null; 132 if (m_adapter != null) 133 { 134 retVal= m_adapter.queryAdapted(); 135 if (retVal == null) 136 { 137 // If this object registered as listener with XAdapter while it was notifying 138 // the listeners then this object might not have been notified. If queryAdapted 139 // returned null then the weak kept object is dead and the listeners have already 140 // been notified. And we missed it. 141 m_adapter.removeReference(this); 142 m_adapter= null; 143 } 144 } 145 return retVal; 146 } 147 } 148