xref: /AOO41X/main/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/ViewContainer.java (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  *  The Contents of this file are made available subject to the terms of
4*cdf0e10cSrcweir  *  the BSD license.
5*cdf0e10cSrcweir  *
6*cdf0e10cSrcweir  *  Copyright 2000, 2010 Oracle and/or its affiliates.
7*cdf0e10cSrcweir  *  All rights reserved.
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  *  Redistribution and use in source and binary forms, with or without
10*cdf0e10cSrcweir  *  modification, are permitted provided that the following conditions
11*cdf0e10cSrcweir  *  are met:
12*cdf0e10cSrcweir  *  1. Redistributions of source code must retain the above copyright
13*cdf0e10cSrcweir  *     notice, this list of conditions and the following disclaimer.
14*cdf0e10cSrcweir  *  2. Redistributions in binary form must reproduce the above copyright
15*cdf0e10cSrcweir  *     notice, this list of conditions and the following disclaimer in the
16*cdf0e10cSrcweir  *     documentation and/or other materials provided with the distribution.
17*cdf0e10cSrcweir  *  3. Neither the name of Sun Microsystems, Inc. nor the names of its
18*cdf0e10cSrcweir  *     contributors may be used to endorse or promote products derived
19*cdf0e10cSrcweir  *     from this software without specific prior written permission.
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22*cdf0e10cSrcweir  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23*cdf0e10cSrcweir  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24*cdf0e10cSrcweir  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25*cdf0e10cSrcweir  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26*cdf0e10cSrcweir  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27*cdf0e10cSrcweir  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28*cdf0e10cSrcweir  *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29*cdf0e10cSrcweir  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
30*cdf0e10cSrcweir  *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
31*cdf0e10cSrcweir  *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32*cdf0e10cSrcweir  *
33*cdf0e10cSrcweir  *************************************************************************/
34*cdf0e10cSrcweir 
35*cdf0e10cSrcweir // __________ Imports __________
36*cdf0e10cSrcweir 
37*cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime;
38*cdf0e10cSrcweir 
39*cdf0e10cSrcweir import java.lang.*;
40*cdf0e10cSrcweir import java.util.*;
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir // __________ Implementation __________
43*cdf0e10cSrcweir 
44*cdf0e10cSrcweir /**
45*cdf0e10cSrcweir  * It's implement a static container which hold
46*cdf0e10cSrcweir  * all opened documents and her views alive.
47*cdf0e10cSrcweir  * It's possible to register/deregister such views,
48*cdf0e10cSrcweir  * to get information about these and it provides
49*cdf0e10cSrcweir  * some global functionality - like termination of
50*cdf0e10cSrcweir  * this demo application.
51*cdf0e10cSrcweir  *
52*cdf0e10cSrcweir  * @author     Andreas Schlüns
53*cdf0e10cSrcweir  * @created    01.03.2002 08:42
54*cdf0e10cSrcweir  */
55*cdf0e10cSrcweir public class ViewContainer extends Thread
56*cdf0e10cSrcweir {
57*cdf0e10cSrcweir     // ____________________
58*cdf0e10cSrcweir 
59*cdf0e10cSrcweir     /**
60*cdf0e10cSrcweir      * provides a singleton view container
61*cdf0e10cSrcweir      * Neccessary for terminate(9 functionality to be able
62*cdf0e10cSrcweir      * to call Runtime.runFinilization().
63*cdf0e10cSrcweir      *
64*cdf0e10cSrcweir      * @return a reference to the singleton ViewContainer instance
65*cdf0e10cSrcweir      */
66*cdf0e10cSrcweir     public static synchronized ViewContainer getGlobalContainer()
67*cdf0e10cSrcweir     {
68*cdf0e10cSrcweir         if (maSingleton==null)
69*cdf0e10cSrcweir             maSingleton=new ViewContainer();
70*cdf0e10cSrcweir         return maSingleton;
71*cdf0e10cSrcweir     }
72*cdf0e10cSrcweir 
73*cdf0e10cSrcweir     // ____________________
74*cdf0e10cSrcweir 
75*cdf0e10cSrcweir     /**
76*cdf0e10cSrcweir      * ctor
77*cdf0e10cSrcweir      * It's private - because nobody should create any instance
78*cdf0e10cSrcweir      * expect the only global one, which wil be created by ourself!
79*cdf0e10cSrcweir      */
80*cdf0e10cSrcweir     private ViewContainer()
81*cdf0e10cSrcweir     {
82*cdf0e10cSrcweir         mlViews          = new Vector();
83*cdf0e10cSrcweir         mlListener       = new Vector();
84*cdf0e10cSrcweir         mbShutdownActive = false       ;
85*cdf0e10cSrcweir         Runtime.getRuntime().addShutdownHook(this);
86*cdf0e10cSrcweir     }
87*cdf0e10cSrcweir 
88*cdf0e10cSrcweir     // ____________________
89*cdf0e10cSrcweir 
90*cdf0e10cSrcweir     /**
91*cdf0e10cSrcweir      * This register a new view inside this global container
92*cdf0e10cSrcweir      * (if it doesnt already exist).
93*cdf0e10cSrcweir      *
94*cdf0e10cSrcweir      * @param   aView       view which whish to be registered inside this container
95*cdf0e10cSrcweir      */
96*cdf0e10cSrcweir     public void addView(Object aView)
97*cdf0e10cSrcweir     {
98*cdf0e10cSrcweir         synchronized(mlViews)
99*cdf0e10cSrcweir         {
100*cdf0e10cSrcweir             if(mlViews.contains(aView)==false)
101*cdf0e10cSrcweir                 mlViews.add(aView);
102*cdf0e10cSrcweir         }
103*cdf0e10cSrcweir     }
104*cdf0e10cSrcweir 
105*cdf0e10cSrcweir     // ____________________
106*cdf0e10cSrcweir 
107*cdf0e10cSrcweir     /**
108*cdf0e10cSrcweir      * This deregister a view from this global container.
109*cdf0e10cSrcweir      * Normaly it should be the last reference to the view
110*cdf0e10cSrcweir      * and her finalize() method should be called.
111*cdf0e10cSrcweir      * If last view will be closed here - we terminate these
112*cdf0e10cSrcweir      * java application too. Because there is no further
113*cdf0e10cSrcweir      * visible frame anymore.
114*cdf0e10cSrcweir      *
115*cdf0e10cSrcweir      * @param aView
116*cdf0e10cSrcweir      *          view object which wish to be deregistered
117*cdf0e10cSrcweir      */
118*cdf0e10cSrcweir     public void removeView(Object aView)
119*cdf0e10cSrcweir     {
120*cdf0e10cSrcweir         int nViewCount = 0;
121*cdf0e10cSrcweir         synchronized(mlViews)
122*cdf0e10cSrcweir         {
123*cdf0e10cSrcweir             if(mlViews.contains(aView)==true)
124*cdf0e10cSrcweir                 mlViews.remove(aView);
125*cdf0e10cSrcweir 
126*cdf0e10cSrcweir             nViewCount = mlViews.size();
127*cdf0e10cSrcweir 
128*cdf0e10cSrcweir             if (nViewCount<1)
129*cdf0e10cSrcweir                 mlViews = null;
130*cdf0e10cSrcweir         }
131*cdf0e10cSrcweir         // If this view is a registered shutdown listener on this view container
132*cdf0e10cSrcweir         // too, we must call his interface and forget him as possible listener.
133*cdf0e10cSrcweir         // It's neccessary to guarantee his dead ...
134*cdf0e10cSrcweir         boolean bShutdownView = false;
135*cdf0e10cSrcweir         synchronized(mlListener)
136*cdf0e10cSrcweir         {
137*cdf0e10cSrcweir             bShutdownView = mlListener.contains(aView);
138*cdf0e10cSrcweir             if (bShutdownView==true)
139*cdf0e10cSrcweir                 mlListener.remove(aView);
140*cdf0e10cSrcweir         }
141*cdf0e10cSrcweir         if (bShutdownView==true)
142*cdf0e10cSrcweir             ((IShutdownListener)aView).shutdown();
143*cdf0e10cSrcweir 
144*cdf0e10cSrcweir         // We use a system.exit() to finish the whole application.
145*cdf0e10cSrcweir         // And further we have registered THIS instance as a possible shutdown
146*cdf0e10cSrcweir         // hook at the runtime class. So our run() method will be called.
147*cdf0e10cSrcweir         // Teh our view container should be empty - but
148*cdf0e10cSrcweir         // our listener container can include some references.
149*cdf0e10cSrcweir         // These objects wich to be informed then and release e.g. some
150*cdf0e10cSrcweir         // remote references.
151*cdf0e10cSrcweir         if (nViewCount<1)
152*cdf0e10cSrcweir         {
153*cdf0e10cSrcweir             boolean bNeccessary = false;
154*cdf0e10cSrcweir             synchronized(this)
155*cdf0e10cSrcweir             {
156*cdf0e10cSrcweir                 bNeccessary = ! mbShutdownActive;
157*cdf0e10cSrcweir             }
158*cdf0e10cSrcweir             if (bNeccessary==true)
159*cdf0e10cSrcweir             {
160*cdf0e10cSrcweir                 System.out.println("call exit(0)!");
161*cdf0e10cSrcweir                 System.exit(0);
162*cdf0e10cSrcweir             }
163*cdf0e10cSrcweir         }
164*cdf0e10cSrcweir     }
165*cdf0e10cSrcweir 
166*cdf0e10cSrcweir     // ____________________
167*cdf0e10cSrcweir 
168*cdf0e10cSrcweir     /**
169*cdf0e10cSrcweir      * add/remove listener for possibe shutdown events
170*cdf0e10cSrcweir      */
171*cdf0e10cSrcweir     public void addListener( IShutdownListener rListener )
172*cdf0e10cSrcweir     {
173*cdf0e10cSrcweir         synchronized(mlListener)
174*cdf0e10cSrcweir         {
175*cdf0e10cSrcweir             if ( ! mlListener.contains(rListener) )
176*cdf0e10cSrcweir                 mlListener.add(rListener);
177*cdf0e10cSrcweir         }
178*cdf0e10cSrcweir     }
179*cdf0e10cSrcweir 
180*cdf0e10cSrcweir     // ____________________
181*cdf0e10cSrcweir 
182*cdf0e10cSrcweir     public void removeListener( IShutdownListener rListener )
183*cdf0e10cSrcweir     {
184*cdf0e10cSrcweir         synchronized(mlListener)
185*cdf0e10cSrcweir         {
186*cdf0e10cSrcweir             if ( mlListener.contains(rListener) )
187*cdf0e10cSrcweir                 mlListener.remove(rListener);
188*cdf0e10cSrcweir         }
189*cdf0e10cSrcweir     }
190*cdf0e10cSrcweir 
191*cdf0e10cSrcweir     // ____________________
192*cdf0e10cSrcweir 
193*cdf0e10cSrcweir     /**
194*cdf0e10cSrcweir      * Is called from current runtime system of the java machine
195*cdf0e10cSrcweir      * on shutdown. We inform all current registered listener and
196*cdf0e10cSrcweir      * views. They should deinitialize her internal things then.
197*cdf0e10cSrcweir      */
198*cdf0e10cSrcweir     public void run()
199*cdf0e10cSrcweir     {
200*cdf0e10cSrcweir         synchronized(this)
201*cdf0e10cSrcweir         {
202*cdf0e10cSrcweir             if (mbShutdownActive)
203*cdf0e10cSrcweir                 return;
204*cdf0e10cSrcweir             mbShutdownActive=true;
205*cdf0e10cSrcweir         }
206*cdf0e10cSrcweir 
207*cdf0e10cSrcweir         while( true )
208*cdf0e10cSrcweir         {
209*cdf0e10cSrcweir             IShutdownListener aListener = null;
210*cdf0e10cSrcweir             synchronized(mlListener)
211*cdf0e10cSrcweir             {
212*cdf0e10cSrcweir                 try{
213*cdf0e10cSrcweir                     aListener = (IShutdownListener)mlListener.firstElement();
214*cdf0e10cSrcweir                 } catch(java.util.NoSuchElementException exEmpty) {}
215*cdf0e10cSrcweir             }
216*cdf0e10cSrcweir             if (aListener==null)
217*cdf0e10cSrcweir                 break;
218*cdf0e10cSrcweir 
219*cdf0e10cSrcweir             aListener.shutdown();
220*cdf0e10cSrcweir             // May this listener has dergeistered himself.
221*cdf0e10cSrcweir             // But if not we must do it for him. Our own
222*cdf0e10cSrcweir             // method "removeListener()" ignore requests for
223*cdf0e10cSrcweir             // already gone listener objects.
224*cdf0e10cSrcweir             removeListener(aListener);
225*cdf0e10cSrcweir         }
226*cdf0e10cSrcweir 
227*cdf0e10cSrcweir         if (mlViews!=null)
228*cdf0e10cSrcweir         {
229*cdf0e10cSrcweir             synchronized(mlViews)
230*cdf0e10cSrcweir             {
231*cdf0e10cSrcweir                 mlViews.clear();
232*cdf0e10cSrcweir                 mlViews = null;
233*cdf0e10cSrcweir             }
234*cdf0e10cSrcweir         }
235*cdf0e10cSrcweir 
236*cdf0e10cSrcweir         if (mlListener!=null)
237*cdf0e10cSrcweir         {
238*cdf0e10cSrcweir             synchronized(mlListener)
239*cdf0e10cSrcweir             {
240*cdf0e10cSrcweir                 mlListener.clear();
241*cdf0e10cSrcweir                 mlListener = null;
242*cdf0e10cSrcweir             }
243*cdf0e10cSrcweir         }
244*cdf0e10cSrcweir     }
245*cdf0e10cSrcweir 
246*cdf0e10cSrcweir     // ____________________
247*cdf0e10cSrcweir 
248*cdf0e10cSrcweir     /**
249*cdf0e10cSrcweir      * @const   BASICNAME   it's used to create uinque names for all regieterd views
250*cdf0e10cSrcweir      */
251*cdf0e10cSrcweir     private static final String BASICNAME = "Document View ";
252*cdf0e10cSrcweir 
253*cdf0e10cSrcweir     // ____________________
254*cdf0e10cSrcweir 
255*cdf0e10cSrcweir     /**
256*cdf0e10cSrcweir      * @member  mbInplace           indicates using of inplace office frames instead of outplace ones
257*cdf0e10cSrcweir      * @member  maSingleton         singleton instance of this view container
258*cdf0e10cSrcweir      * @member  mlViews             list of all currently registered document views
259*cdf0e10cSrcweir      * @member  mlListener          list of all currently registered shutdown listener
260*cdf0e10cSrcweir      * @member  mbShutdownActive    if this shutdown hook already was started it's not a good idea to
261*cdf0e10cSrcweir      *                              call System.exit() again for other conditions.
262*cdf0e10cSrcweir      *                              We supress it by using this variable!
263*cdf0e10cSrcweir      */
264*cdf0e10cSrcweir     public  static boolean       mbInplace   = false ;
265*cdf0e10cSrcweir     private static ViewContainer maSingleton = null  ;
266*cdf0e10cSrcweir     private        Vector        mlViews             ;
267*cdf0e10cSrcweir     private        Vector        mlListener          ;
268*cdf0e10cSrcweir     private        boolean       mbShutdownActive    ;
269*cdf0e10cSrcweir }
270