1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_filter.hxx"
26 
27 #include "lateinitlistener.hxx"
28 #include "lateinitthread.hxx"
29 
30 //_______________________________________________
31 // includes
32 #include <rtl/ustring.hxx>
33 
34 //_______________________________________________
35 // namespace
36 
37 namespace filter{
38     namespace config{
39 
40 namespace css = ::com::sun::star;
41 
42 //_______________________________________________
43 // definitions
44 
45 /*-----------------------------------------------
46     14.08.2003 07:35
47 -----------------------------------------------*/
LateInitListener(const css::uno::Reference<css::lang::XMultiServiceFactory> & xSMGR)48 LateInitListener::LateInitListener(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
49     : BaseLock(     )
50     , m_xSMGR (xSMGR)
51 {
52     // important to do so ...
53     // Otherwhise the temp. reference to ourselves
54     // will kill us at realeasing time!
55     osl_incrementInterlockedCount( &m_refCount );
56 
57     m_xBroadcaster = css::uno::Reference< css::document::XEventBroadcaster >(
58         m_xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.GlobalEventBroadcaster")),
59         css::uno::UNO_QUERY);
60 
61     m_xBroadcaster->addEventListener(static_cast< css::document::XEventListener* >(this));
62 
63     osl_decrementInterlockedCount( &m_refCount );
64 }
65 
66 /*-----------------------------------------------
67     14.08.2003 07:25
68 -----------------------------------------------*/
~LateInitListener()69 LateInitListener::~LateInitListener()
70 {
71 }
72 
73 /*-----------------------------------------------
74     14.08.2003 08:45
75 -----------------------------------------------*/
notifyEvent(const css::document::EventObject & aEvent)76 void SAL_CALL LateInitListener::notifyEvent(const css::document::EventObject& aEvent)
77     throw(css::uno::RuntimeException)
78 {
79     // wait for events, which indicates finished open of the first document
80     if (
81         (aEvent.EventName.equalsAscii("OnNew") ) ||
82         (aEvent.EventName.equalsAscii("OnLoad"))
83        )
84     {
85         // this thread must be started one times only ...
86         // cancel listener connection before!
87 
88         // SAFE ->
89         ::osl::ResettableMutexGuard aLock(m_aLock);
90 
91         if ( !m_xBroadcaster.is() )
92             // the beauty of multi-threading ... OnLoad can be notified synchronously or asynchronously. In particular,
93             // SFX-based documents notify it synchronously, database documents do it asynchronously.
94             // Now if multiple documents are opened "at the same time", it is well possible that we get two events from
95             // different threads, where upon the first event, we already remove ourself from m_xBroadcaster, and start
96             // the thread, nonetheless there's also a second notification "in the queue", which will arrive short
97             // thereafter.
98             // In such a case, simply ignore this second event.
99             return;
100 
101         m_xBroadcaster->removeEventListener(static_cast< css::document::XEventListener* >(this));
102         m_xBroadcaster.clear();
103 
104         aLock.clear();
105         // <- SAFE
106 
107         LateInitThread* pThread = new LateInitThread();
108         pThread->create();
109     }
110 }
111 
112 /*-----------------------------------------------
113     14.08.2003 07:48
114 -----------------------------------------------*/
disposing(const css::lang::EventObject &)115 void SAL_CALL LateInitListener::disposing(const css::lang::EventObject& /* aEvent */ )
116     throw(css::uno::RuntimeException)
117 {
118     // ???
119     // Normaly it should never be called. Because we cancel our listener connection
120     // if we got the event about finished open of the first office document.
121     // But if this method was reached, it indicates an office, which was started
122     // (might as remote script container for an external API client) but not realy used.
123 
124     // SAFE ->
125     ::osl::ResettableMutexGuard aLock(m_aLock);
126     m_xBroadcaster.clear();
127     aLock.clear();
128     // <- SAFE
129 }
130 
131     } // namespace config
132 } // namespace filter
133