1*34dd1e25SAndrew Rist /************************************************************** 2*34dd1e25SAndrew Rist * 3*34dd1e25SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*34dd1e25SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*34dd1e25SAndrew Rist * distributed with this work for additional information 6*34dd1e25SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*34dd1e25SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*34dd1e25SAndrew Rist * "License"); you may not use this file except in compliance 9*34dd1e25SAndrew Rist * with the License. You may obtain a copy of the License at 10*34dd1e25SAndrew Rist * 11*34dd1e25SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*34dd1e25SAndrew Rist * 13*34dd1e25SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*34dd1e25SAndrew Rist * software distributed under the License is distributed on an 15*34dd1e25SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*34dd1e25SAndrew Rist * KIND, either express or implied. See the License for the 17*34dd1e25SAndrew Rist * specific language governing permissions and limitations 18*34dd1e25SAndrew Rist * under the License. 19*34dd1e25SAndrew Rist * 20*34dd1e25SAndrew Rist *************************************************************/ 21*34dd1e25SAndrew Rist 22*34dd1e25SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // __________ Imports __________ 25cdf0e10cSrcweir 26cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime; 27cdf0e10cSrcweir 28cdf0e10cSrcweir import java.lang.*; 29cdf0e10cSrcweir import java.util.*; 30cdf0e10cSrcweir 31cdf0e10cSrcweir // __________ Implementation __________ 32cdf0e10cSrcweir 33cdf0e10cSrcweir /** 34cdf0e10cSrcweir * It's implement a static container which hold 35cdf0e10cSrcweir * all opened documents and her views alive. 36cdf0e10cSrcweir * It's possible to register/deregister such views, 37cdf0e10cSrcweir * to get information about these and it provides 38cdf0e10cSrcweir * some global functionality - like termination of 39cdf0e10cSrcweir * this demo application. 40cdf0e10cSrcweir * 41cdf0e10cSrcweir * @author Andreas Schlüns 42cdf0e10cSrcweir * @created 01.03.2002 08:42 43cdf0e10cSrcweir */ 44cdf0e10cSrcweir public class ViewContainer extends Thread 45cdf0e10cSrcweir { 46cdf0e10cSrcweir // ____________________ 47cdf0e10cSrcweir 48cdf0e10cSrcweir /** 49cdf0e10cSrcweir * provides a singleton view container 50cdf0e10cSrcweir * Neccessary for terminate(9 functionality to be able 51cdf0e10cSrcweir * to call Runtime.runFinilization(). 52cdf0e10cSrcweir * 53cdf0e10cSrcweir * @return a reference to the singleton ViewContainer instance 54cdf0e10cSrcweir */ getGlobalContainer()55cdf0e10cSrcweir public static synchronized ViewContainer getGlobalContainer() 56cdf0e10cSrcweir { 57cdf0e10cSrcweir if (maSingleton==null) 58cdf0e10cSrcweir maSingleton=new ViewContainer(); 59cdf0e10cSrcweir return maSingleton; 60cdf0e10cSrcweir } 61cdf0e10cSrcweir 62cdf0e10cSrcweir // ____________________ 63cdf0e10cSrcweir 64cdf0e10cSrcweir /** 65cdf0e10cSrcweir * ctor 66cdf0e10cSrcweir * It's private - because nobody should create any instance 67cdf0e10cSrcweir * expect the only global one, which wil be created by ourself! 68cdf0e10cSrcweir */ ViewContainer()69cdf0e10cSrcweir private ViewContainer() 70cdf0e10cSrcweir { 71cdf0e10cSrcweir mlViews = new Vector(); 72cdf0e10cSrcweir mlListener = new Vector(); 73cdf0e10cSrcweir mbShutdownActive = false ; 74cdf0e10cSrcweir Runtime.getRuntime().addShutdownHook(this); 75cdf0e10cSrcweir } 76cdf0e10cSrcweir 77cdf0e10cSrcweir // ____________________ 78cdf0e10cSrcweir 79cdf0e10cSrcweir /** 80cdf0e10cSrcweir * This register a new view inside this global container 81cdf0e10cSrcweir * (if it doesnt already exist). 82cdf0e10cSrcweir * 83cdf0e10cSrcweir * @param aView view which whish to be registered inside this container 84cdf0e10cSrcweir */ addView(Object aView)85cdf0e10cSrcweir public void addView(Object aView) 86cdf0e10cSrcweir { 87cdf0e10cSrcweir synchronized(mlViews) 88cdf0e10cSrcweir { 89cdf0e10cSrcweir if(mlViews.contains(aView)==false) 90cdf0e10cSrcweir mlViews.add(aView); 91cdf0e10cSrcweir } 92cdf0e10cSrcweir } 93cdf0e10cSrcweir 94cdf0e10cSrcweir // ____________________ 95cdf0e10cSrcweir 96cdf0e10cSrcweir /** 97cdf0e10cSrcweir * This deregister a view from this global container. 98cdf0e10cSrcweir * Normaly it should be the last reference to the view 99cdf0e10cSrcweir * and her finalize() method should be called. 100cdf0e10cSrcweir * If last view will be closed here - we terminate these 101cdf0e10cSrcweir * java application too. Because there is no further 102cdf0e10cSrcweir * visible frame anymore. 103cdf0e10cSrcweir * 104cdf0e10cSrcweir * @param aView 105cdf0e10cSrcweir * view object which wish to be deregistered 106cdf0e10cSrcweir */ removeView(Object aView)107cdf0e10cSrcweir public void removeView(Object aView) 108cdf0e10cSrcweir { 109cdf0e10cSrcweir int nViewCount = 0; 110cdf0e10cSrcweir synchronized(mlViews) 111cdf0e10cSrcweir { 112cdf0e10cSrcweir if(mlViews.contains(aView)==true) 113cdf0e10cSrcweir mlViews.remove(aView); 114cdf0e10cSrcweir 115cdf0e10cSrcweir nViewCount = mlViews.size(); 116cdf0e10cSrcweir 117cdf0e10cSrcweir if (nViewCount<1) 118cdf0e10cSrcweir mlViews = null; 119cdf0e10cSrcweir } 120cdf0e10cSrcweir // If this view is a registered shutdown listener on this view container 121cdf0e10cSrcweir // too, we must call his interface and forget him as possible listener. 122cdf0e10cSrcweir // It's neccessary to guarantee his dead ... 123cdf0e10cSrcweir boolean bShutdownView = false; 124cdf0e10cSrcweir synchronized(mlListener) 125cdf0e10cSrcweir { 126cdf0e10cSrcweir bShutdownView = mlListener.contains(aView); 127cdf0e10cSrcweir if (bShutdownView==true) 128cdf0e10cSrcweir mlListener.remove(aView); 129cdf0e10cSrcweir } 130cdf0e10cSrcweir if (bShutdownView==true) 131cdf0e10cSrcweir ((IShutdownListener)aView).shutdown(); 132cdf0e10cSrcweir 133cdf0e10cSrcweir // We use a system.exit() to finish the whole application. 134cdf0e10cSrcweir // And further we have registered THIS instance as a possible shutdown 135cdf0e10cSrcweir // hook at the runtime class. So our run() method will be called. 136cdf0e10cSrcweir // Teh our view container should be empty - but 137cdf0e10cSrcweir // our listener container can include some references. 138cdf0e10cSrcweir // These objects wich to be informed then and release e.g. some 139cdf0e10cSrcweir // remote references. 140cdf0e10cSrcweir if (nViewCount<1) 141cdf0e10cSrcweir { 142cdf0e10cSrcweir boolean bNeccessary = false; 143cdf0e10cSrcweir synchronized(this) 144cdf0e10cSrcweir { 145cdf0e10cSrcweir bNeccessary = ! mbShutdownActive; 146cdf0e10cSrcweir } 147cdf0e10cSrcweir if (bNeccessary==true) 148cdf0e10cSrcweir { 149cdf0e10cSrcweir System.out.println("call exit(0)!"); 150cdf0e10cSrcweir System.exit(0); 151cdf0e10cSrcweir } 152cdf0e10cSrcweir } 153cdf0e10cSrcweir } 154cdf0e10cSrcweir 155cdf0e10cSrcweir // ____________________ 156cdf0e10cSrcweir 157cdf0e10cSrcweir /** 158cdf0e10cSrcweir * add/remove listener for possibe shutdown events 159cdf0e10cSrcweir */ addListener( IShutdownListener rListener )160cdf0e10cSrcweir public void addListener( IShutdownListener rListener ) 161cdf0e10cSrcweir { 162cdf0e10cSrcweir synchronized(mlListener) 163cdf0e10cSrcweir { 164cdf0e10cSrcweir if ( ! mlListener.contains(rListener) ) 165cdf0e10cSrcweir mlListener.add(rListener); 166cdf0e10cSrcweir } 167cdf0e10cSrcweir } 168cdf0e10cSrcweir 169cdf0e10cSrcweir // ____________________ 170cdf0e10cSrcweir removeListener( IShutdownListener rListener )171cdf0e10cSrcweir public void removeListener( IShutdownListener rListener ) 172cdf0e10cSrcweir { 173cdf0e10cSrcweir synchronized(mlListener) 174cdf0e10cSrcweir { 175cdf0e10cSrcweir if ( mlListener.contains(rListener) ) 176cdf0e10cSrcweir mlListener.remove(rListener); 177cdf0e10cSrcweir } 178cdf0e10cSrcweir } 179cdf0e10cSrcweir 180cdf0e10cSrcweir // ____________________ 181cdf0e10cSrcweir 182cdf0e10cSrcweir /** 183cdf0e10cSrcweir * Is called from current runtime system of the java machine 184cdf0e10cSrcweir * on shutdown. We inform all current registered listener and 185cdf0e10cSrcweir * views. They should deinitialize her internal things then. 186cdf0e10cSrcweir */ run()187cdf0e10cSrcweir public void run() 188cdf0e10cSrcweir { 189cdf0e10cSrcweir synchronized(this) 190cdf0e10cSrcweir { 191cdf0e10cSrcweir if (mbShutdownActive) 192cdf0e10cSrcweir return; 193cdf0e10cSrcweir mbShutdownActive=true; 194cdf0e10cSrcweir } 195cdf0e10cSrcweir 196cdf0e10cSrcweir while( true ) 197cdf0e10cSrcweir { 198cdf0e10cSrcweir IShutdownListener aListener = null; 199cdf0e10cSrcweir synchronized(mlListener) 200cdf0e10cSrcweir { 201cdf0e10cSrcweir try{ 202cdf0e10cSrcweir aListener = (IShutdownListener)mlListener.firstElement(); 203cdf0e10cSrcweir } catch(java.util.NoSuchElementException exEmpty) {} 204cdf0e10cSrcweir } 205cdf0e10cSrcweir if (aListener==null) 206cdf0e10cSrcweir break; 207cdf0e10cSrcweir 208cdf0e10cSrcweir aListener.shutdown(); 209cdf0e10cSrcweir // May this listener has dergeistered himself. 210cdf0e10cSrcweir // But if not we must do it for him. Our own 211cdf0e10cSrcweir // method "removeListener()" ignore requests for 212cdf0e10cSrcweir // already gone listener objects. 213cdf0e10cSrcweir removeListener(aListener); 214cdf0e10cSrcweir } 215cdf0e10cSrcweir 216cdf0e10cSrcweir if (mlViews!=null) 217cdf0e10cSrcweir { 218cdf0e10cSrcweir synchronized(mlViews) 219cdf0e10cSrcweir { 220cdf0e10cSrcweir mlViews.clear(); 221cdf0e10cSrcweir mlViews = null; 222cdf0e10cSrcweir } 223cdf0e10cSrcweir } 224cdf0e10cSrcweir 225cdf0e10cSrcweir if (mlListener!=null) 226cdf0e10cSrcweir { 227cdf0e10cSrcweir synchronized(mlListener) 228cdf0e10cSrcweir { 229cdf0e10cSrcweir mlListener.clear(); 230cdf0e10cSrcweir mlListener = null; 231cdf0e10cSrcweir } 232cdf0e10cSrcweir } 233cdf0e10cSrcweir } 234cdf0e10cSrcweir 235cdf0e10cSrcweir // ____________________ 236cdf0e10cSrcweir 237cdf0e10cSrcweir /** 238cdf0e10cSrcweir * @const BASICNAME it's used to create uinque names for all regieterd views 239cdf0e10cSrcweir */ 240cdf0e10cSrcweir private static final String BASICNAME = "Document View "; 241cdf0e10cSrcweir 242cdf0e10cSrcweir // ____________________ 243cdf0e10cSrcweir 244cdf0e10cSrcweir /** 245cdf0e10cSrcweir * @member mbInplace indicates using of inplace office frames instead of outplace ones 246cdf0e10cSrcweir * @member maSingleton singleton instance of this view container 247cdf0e10cSrcweir * @member mlViews list of all currently registered document views 248cdf0e10cSrcweir * @member mlListener list of all currently registered shutdown listener 249cdf0e10cSrcweir * @member mbShutdownActive if this shutdown hook already was started it's not a good idea to 250cdf0e10cSrcweir * call System.exit() again for other conditions. 251cdf0e10cSrcweir * We supress it by using this variable! 252cdf0e10cSrcweir */ 253cdf0e10cSrcweir public static boolean mbInplace = false ; 254cdf0e10cSrcweir private static ViewContainer maSingleton = null ; 255cdf0e10cSrcweir private Vector mlViews ; 256cdf0e10cSrcweir private Vector mlListener ; 257cdf0e10cSrcweir private boolean mbShutdownActive ; 258cdf0e10cSrcweir } 259