/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ package com.sun.star.uno; /** * This class holds weak reference to an object. * *

It actually holds a reference to a com.sun.star.XAdapter * implementation and obtains a hard reference if necessary. */ public class WeakReference { private OWeakRefListener m_listener; // There is no default constructor. Every instance must register itself with the // XAdapter interface, which is done in the constructors. Assume we have this code // WeakReference ref= new WeakReference(); // ref = someOtherWeakReference; // // ref would not be notified (XReference.dispose()) because it did not register // itself. Therefore the XAdapter would be kept alive although this is not // necessary. /** * Creates an instance of this class. * * @param obj another instance that is to be copied. */ public WeakReference(WeakReference obj) { if (obj == null) { return; } Object weakImpl = obj.get(); if (weakImpl == null) { return; } XWeak weak = UnoRuntime.queryInterface(XWeak.class, weakImpl); if (weak != null) { XAdapter adapter = weak.queryAdapter(); if (adapter != null) m_listener = new OWeakRefListener(adapter); } } /** * Creates an instance of this class. * * @param obj XWeak implementation. */ public WeakReference(Object obj) { XWeak weak= UnoRuntime.queryInterface(XWeak.class, obj); if (weak != null) { XAdapter adapter= weak.queryAdapter(); if (adapter != null) m_listener= new OWeakRefListener(adapter); } } /** * Returns a hard reference to the object that is kept weak by this class. * * @return a hard reference to the XWeak implementation. */ public Object get() { if (m_listener != null) return m_listener.get(); return null; } } /** * Implementation of com.sun.star.uno.XReference for use with WeakReference. * *

It keeps the XAdapter implementation and registers always with it. * Deregistering occurs on notification by the adapter and the adapter is * released.

*/ class OWeakRefListener implements XReference { private XAdapter m_adapter; /** * The constructor registered this object with adapter. * * @param adapter the XAdapter implementation. */ OWeakRefListener( XAdapter adapter) { m_adapter= adapter; m_adapter.addReference(this); } /** * Method of com.sun.star.uno.XReference. * *

When called, it deregisters this object with the adapter and releases * the reference to it.

*/ synchronized public void dispose() { if (m_adapter != null) { m_adapter.removeReference(this); m_adapter= null; } } /** * Obtains a hard reference to the object which is kept weak by the adapter * and returns it. * * @return hard reference to the otherwise weakly kept object. */ synchronized Object get() { Object retVal= null; if (m_adapter != null) { retVal= m_adapter.queryAdapted(); if (retVal == null) { // If this object registered as listener with XAdapter while it was notifying // the listeners then this object might not have been notified. If queryAdapted // returned null then the weak kept object is dead and the listeners have already // been notified. And we missed it. m_adapter.removeReference(this); m_adapter= null; } } return retVal; } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */