1*a5b190bfSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*a5b190bfSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*a5b190bfSAndrew Rist * or more contributor license agreements. See the NOTICE file 5*a5b190bfSAndrew Rist * distributed with this work for additional information 6*a5b190bfSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*a5b190bfSAndrew Rist * to you under the Apache License, Version 2.0 (the 8*a5b190bfSAndrew Rist * "License"); you may not use this file except in compliance 9*a5b190bfSAndrew Rist * with the License. You may obtain a copy of the License at 10*a5b190bfSAndrew Rist * 11*a5b190bfSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*a5b190bfSAndrew Rist * 13*a5b190bfSAndrew Rist * Unless required by applicable law or agreed to in writing, 14*a5b190bfSAndrew Rist * software distributed under the License is distributed on an 15*a5b190bfSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*a5b190bfSAndrew Rist * KIND, either express or implied. See the License for the 17*a5b190bfSAndrew Rist * specific language governing permissions and limitations 18*a5b190bfSAndrew Rist * under the License. 19*a5b190bfSAndrew Rist * 20*a5b190bfSAndrew Rist *************************************************************/ 21*a5b190bfSAndrew Rist 22*a5b190bfSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir package com.sun.star.lib.uno.helper; 25cdf0e10cSrcweir import com.sun.star.lang.XComponent; 26cdf0e10cSrcweir import com.sun.star.lang.XEventListener; 27cdf0e10cSrcweir import com.sun.star.lang.EventObject; 28cdf0e10cSrcweir import com.sun.star.uno.Type; 29cdf0e10cSrcweir 30cdf0e10cSrcweir /** This class can be used as the base class for UNO components. In addition to the functionality ,which 31cdf0e10cSrcweir * is inherited from WeakBase, it implements com.sun.star.lang.XComponent. 32cdf0e10cSrcweir */ 33cdf0e10cSrcweir public class ComponentBase extends WeakBase implements XComponent 34cdf0e10cSrcweir { 35cdf0e10cSrcweir private final boolean DEBUG= false; 36cdf0e10cSrcweir protected MultiTypeInterfaceContainer listenerContainer; 37cdf0e10cSrcweir protected boolean bInDispose= false; 38cdf0e10cSrcweir protected boolean bDisposed= false; 39cdf0e10cSrcweir static final Type EVT_LISTENER_TYPE= new Type(XEventListener.class); 40cdf0e10cSrcweir 41cdf0e10cSrcweir 42cdf0e10cSrcweir /** Creates a new instance of CompBase */ ComponentBase()43cdf0e10cSrcweir public ComponentBase() 44cdf0e10cSrcweir { 45cdf0e10cSrcweir super(); 46cdf0e10cSrcweir listenerContainer= new MultiTypeInterfaceContainer(); 47cdf0e10cSrcweir } 48cdf0e10cSrcweir 49cdf0e10cSrcweir /** Override to perform extra clean-up work. Provided for subclasses. It is 50cdf0e10cSrcweir called during dispose() 51cdf0e10cSrcweir */ preDisposing()52cdf0e10cSrcweir protected void preDisposing() 53cdf0e10cSrcweir { 54cdf0e10cSrcweir } 55cdf0e10cSrcweir /** Override to become notified right before the disposing action is performed. 56cdf0e10cSrcweir */ postDisposing()57cdf0e10cSrcweir protected void postDisposing() 58cdf0e10cSrcweir { 59cdf0e10cSrcweir } 60cdf0e10cSrcweir 61cdf0e10cSrcweir 62cdf0e10cSrcweir /** Method of XComponent. It is called by the owning client when the component is not needed 63cdf0e10cSrcweir * anymore. The registered listeners are notified that this method has been called. 64cdf0e10cSrcweir */ dispose()65cdf0e10cSrcweir public void dispose() 66cdf0e10cSrcweir { 67cdf0e10cSrcweir // Determine in a thread-safe way if this is the first call to this method. 68cdf0e10cSrcweir // Only then we proceed with the notification of event listeners. 69cdf0e10cSrcweir // It is an error to call this method more then once. 70cdf0e10cSrcweir boolean bDoDispose= false; 71cdf0e10cSrcweir synchronized (this) 72cdf0e10cSrcweir { 73cdf0e10cSrcweir if ( ! bInDispose && ! bDisposed) 74cdf0e10cSrcweir { 75cdf0e10cSrcweir bDoDispose= true; 76cdf0e10cSrcweir bInDispose= true; 77cdf0e10cSrcweir } 78cdf0e10cSrcweir } 79cdf0e10cSrcweir // The notification occures in an unsynchronized block in order to avoid 80cdf0e10cSrcweir // deadlocks if one of the listeners calls back in a different thread on 81cdf0e10cSrcweir // a synchronized method which uses the same object. 82cdf0e10cSrcweir if (bDoDispose) 83cdf0e10cSrcweir { 84cdf0e10cSrcweir try 85cdf0e10cSrcweir { 86cdf0e10cSrcweir preDisposing(); 87cdf0e10cSrcweir listenerContainer.disposeAndClear(new EventObject(this)); 88cdf0e10cSrcweir //notify subclasses that disposing is in progress 89cdf0e10cSrcweir postDisposing(); 90cdf0e10cSrcweir } 91cdf0e10cSrcweir finally 92cdf0e10cSrcweir { 93cdf0e10cSrcweir // finally makes sure that the flags are set even if a RuntimeException is thrown. 94cdf0e10cSrcweir // That ensures that this function is only called once. 95cdf0e10cSrcweir bDisposed= true; 96cdf0e10cSrcweir bInDispose= false; 97cdf0e10cSrcweir } 98cdf0e10cSrcweir } 99cdf0e10cSrcweir else 100cdf0e10cSrcweir { 101cdf0e10cSrcweir // in a multithreaded environment, it can't be avoided, that dispose is called twice. 102cdf0e10cSrcweir // However this condition is traced, because it MAY indicate an error. 103cdf0e10cSrcweir if (DEBUG) 104cdf0e10cSrcweir System.out.println("OComponentHelper::dispose() - dispose called twice" ); 105cdf0e10cSrcweir } 106cdf0e10cSrcweir } 107cdf0e10cSrcweir 108cdf0e10cSrcweir /** Method of XComponent. 109cdf0e10cSrcweir */ removeEventListener(XEventListener xEventListener)110cdf0e10cSrcweir public void removeEventListener(XEventListener xEventListener) 111cdf0e10cSrcweir { 112cdf0e10cSrcweir listenerContainer.removeInterface( EVT_LISTENER_TYPE, xEventListener); 113cdf0e10cSrcweir } 114cdf0e10cSrcweir addEventListener(XEventListener listener)115cdf0e10cSrcweir public void addEventListener(XEventListener listener) 116cdf0e10cSrcweir { 117cdf0e10cSrcweir boolean bDoDispose= false; 118cdf0e10cSrcweir synchronized (this) 119cdf0e10cSrcweir { 120cdf0e10cSrcweir if (bDisposed || bInDispose) 121cdf0e10cSrcweir bDoDispose= true; 122cdf0e10cSrcweir else 123cdf0e10cSrcweir listenerContainer.addInterface(EVT_LISTENER_TYPE, listener); 124cdf0e10cSrcweir } 125cdf0e10cSrcweir if (bDoDispose ) 126cdf0e10cSrcweir { 127cdf0e10cSrcweir listener.disposing( new EventObject(this)); 128cdf0e10cSrcweir } 129cdf0e10cSrcweir } 130cdf0e10cSrcweir finalize()131cdf0e10cSrcweir protected void finalize() throws Throwable 132cdf0e10cSrcweir { 133cdf0e10cSrcweir if ( ! bInDispose && ! bDisposed) 134cdf0e10cSrcweir dispose(); 135cdf0e10cSrcweir super.finalize(); 136cdf0e10cSrcweir } 137cdf0e10cSrcweir } 138