1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_framework.hxx"
30 
31 #include "framework/preventduplicateinteraction.hxx"
32 
33 //_________________________________________________________________________________________________________________
34 //	my own includes
35 //_________________________________________________________________________________________________________________
36 
37 //_________________________________________________________________________________________________________________
38 //	interface includes
39 //_________________________________________________________________________________________________________________
40 #include <com/sun/star/task/XInteractionAbort.hpp>
41 #include <com/sun/star/task/XInteractionRetry.hpp>
42 
43 //_________________________________________________________________________________________________________________
44 //	other includes
45 //_________________________________________________________________________________________________________________
46 
47 //_________________________________________________________________________________________________________________
48 //	namespace
49 //_________________________________________________________________________________________________________________
50 
51 namespace framework{
52 
53 namespace css = ::com::sun::star;
54 
55 //_________________________________________________________________________________________________________________
56 //	exported const
57 //_________________________________________________________________________________________________________________
58 
59 #define IMPLEMENTATIONNAME_UIINTERACTIONHANDLER                 ::rtl::OUString::createFromAscii("com.sun.star.comp.uui.UUIInteractionHandler")
60 
61 //_________________________________________________________________________________________________________________
62 //	exported definitions
63 //_________________________________________________________________________________________________________________
64 
65 //_________________________________________________________________________________________________________________
66 
67 PreventDuplicateInteraction::PreventDuplicateInteraction(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
68     : ThreadHelpBase2()
69     , m_xSMGR(xSMGR)
70 {
71 }
72 
73 //_________________________________________________________________________________________________________________
74 
75 PreventDuplicateInteraction::~PreventDuplicateInteraction()
76 {
77 }
78 
79 //_________________________________________________________________________________________________________________
80 
81 void PreventDuplicateInteraction::setHandler(const css::uno::Reference< css::task::XInteractionHandler >& xHandler)
82 {
83     // SAFE ->
84     ::osl::ResettableMutexGuard aLock(m_aLock);
85     m_xHandler = xHandler;
86     aLock.clear();
87     // <- SAFE
88 }
89 
90 //_________________________________________________________________________________________________________________
91 
92 void PreventDuplicateInteraction::useDefaultUUIHandler()
93 {
94     // SAFE ->
95     ::osl::ResettableMutexGuard aLock(m_aLock);
96     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
97     aLock.clear();
98     // <- SAFE
99 
100     css::uno::Reference< css::task::XInteractionHandler > xHandler(
101                             xSMGR->createInstance(IMPLEMENTATIONNAME_UIINTERACTIONHANDLER),
102                             css::uno::UNO_QUERY_THROW);
103 
104     // SAFE ->
105     aLock.reset();
106     m_xHandler = xHandler;
107     aLock.clear();
108     // <- SAFE
109 }
110 
111 //_________________________________________________________________________________________________________________
112 css::uno::Any SAL_CALL PreventDuplicateInteraction::queryInterface( const css::uno::Type& aType )
113     throw (css::uno::RuntimeException)
114 {
115     if ( aType.equals( XInteractionHandler2::static_type() ) )
116     {
117         ::osl::ResettableMutexGuard aLock(m_aLock);
118         css::uno::Reference< css::task::XInteractionHandler2 > xHandler( m_xHandler, css::uno::UNO_QUERY );
119         if ( !xHandler.is() )
120             return css::uno::Any();
121     }
122     return ::cppu::WeakImplHelper1< css::task::XInteractionHandler2 >::queryInterface( aType );
123 }
124 
125 //_________________________________________________________________________________________________________________
126 
127 void SAL_CALL PreventDuplicateInteraction::handle(const css::uno::Reference< css::task::XInteractionRequest >& xRequest)
128     throw(css::uno::RuntimeException)
129 {
130     css::uno::Any aRequest  = xRequest->getRequest();
131     sal_Bool      bHandleIt = sal_True;
132 
133     // SAFE ->
134     ::osl::ResettableMutexGuard aLock(m_aLock);
135 
136     InteractionList::iterator pIt;
137     for (  pIt  = m_lInteractionRules.begin();
138            pIt != m_lInteractionRules.end()  ;
139          ++pIt                               )
140     {
141         InteractionInfo& rInfo = *pIt;
142 
143         if (aRequest.isExtractableTo(rInfo.m_aInteraction))
144         {
145             ++rInfo.m_nCallCount;
146             rInfo.m_xRequest = xRequest;
147             bHandleIt = (rInfo.m_nCallCount <= rInfo.m_nMaxCount);
148             break;
149         }
150     }
151 
152     css::uno::Reference< css::task::XInteractionHandler > xHandler = m_xHandler;
153 
154     aLock.clear();
155     // <- SAFE
156 
157     if (
158         (bHandleIt    ) &&
159         (xHandler.is())
160        )
161     {
162         xHandler->handle(xRequest);
163     }
164     else
165     {
166         const css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > lContinuations = xRequest->getContinuations();
167         sal_Int32 c = lContinuations.getLength();
168         sal_Int32 i = 0;
169         for (i=0; i<c; ++i)
170         {
171             css::uno::Reference< css::task::XInteractionAbort > xAbort(lContinuations[i], css::uno::UNO_QUERY);
172             if (xAbort.is())
173             {
174                 xAbort->select();
175                 break;
176             }
177         }
178     }
179 }
180 
181 //_________________________________________________________________________________________________________________
182 
183 ::sal_Bool SAL_CALL PreventDuplicateInteraction::handleInteractionRequest( const css::uno::Reference< css::task::XInteractionRequest >& xRequest )
184             throw (css::uno::RuntimeException)
185 {
186     css::uno::Any aRequest  = xRequest->getRequest();
187     sal_Bool      bHandleIt = sal_True;
188 
189     // SAFE ->
190     ::osl::ResettableMutexGuard aLock(m_aLock);
191 
192     InteractionList::iterator pIt;
193     for (  pIt  = m_lInteractionRules.begin();
194            pIt != m_lInteractionRules.end()  ;
195          ++pIt                               )
196     {
197         InteractionInfo& rInfo = *pIt;
198 
199         if (aRequest.isExtractableTo(rInfo.m_aInteraction))
200         {
201             ++rInfo.m_nCallCount;
202             rInfo.m_xRequest = xRequest;
203             bHandleIt = (rInfo.m_nCallCount <= rInfo.m_nMaxCount);
204             break;
205         }
206     }
207 
208     css::uno::Reference< css::task::XInteractionHandler2 > xHandler( m_xHandler, css::uno::UNO_QUERY );
209     OSL_ENSURE( xHandler.is() || !m_xHandler.is(),
210         "PreventDuplicateInteraction::handleInteractionRequest: inconsistency!" );
211 
212     aLock.clear();
213     // <- SAFE
214 
215     if (
216         (bHandleIt    ) &&
217         (xHandler.is())
218        )
219     {
220         return xHandler->handleInteractionRequest(xRequest);
221     }
222     else
223     {
224         const css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > lContinuations = xRequest->getContinuations();
225         sal_Int32 c = lContinuations.getLength();
226         sal_Int32 i = 0;
227         for (i=0; i<c; ++i)
228         {
229             css::uno::Reference< css::task::XInteractionAbort > xAbort(lContinuations[i], css::uno::UNO_QUERY);
230             if (xAbort.is())
231             {
232                 xAbort->select();
233                 break;
234             }
235         }
236     }
237     return false;
238 }
239 
240 //_________________________________________________________________________________________________________________
241 
242 void PreventDuplicateInteraction::addInteractionRule(const PreventDuplicateInteraction::InteractionInfo& aInteractionInfo)
243 {
244     // SAFE ->
245     ::osl::ResettableMutexGuard aLock(m_aLock);
246 
247     InteractionList::iterator pIt;
248     for (  pIt  = m_lInteractionRules.begin();
249            pIt != m_lInteractionRules.end()  ;
250          ++pIt                               )
251     {
252         InteractionInfo& rInfo = *pIt;
253         if (rInfo.m_aInteraction == aInteractionInfo.m_aInteraction)
254         {
255             rInfo.m_nMaxCount  = aInteractionInfo.m_nMaxCount ;
256             rInfo.m_nCallCount = aInteractionInfo.m_nCallCount;
257             return;
258         }
259     }
260 
261     m_lInteractionRules.push_back(aInteractionInfo);
262 
263     aLock.clear();
264     // <- SAFE
265 }
266 
267 //_________________________________________________________________________________________________________________
268 
269 sal_Bool PreventDuplicateInteraction::getInteractionInfo(const css::uno::Type&                               aInteraction,
270                                                                PreventDuplicateInteraction::InteractionInfo* pReturn     ) const
271 {
272     // SAFE ->
273     ::osl::ResettableMutexGuard aLock(m_aLock);
274 
275     PreventDuplicateInteraction::InteractionList::const_iterator pIt;
276     for (  pIt  = m_lInteractionRules.begin();
277            pIt != m_lInteractionRules.end()  ;
278          ++pIt                               )
279     {
280         const PreventDuplicateInteraction::InteractionInfo& rInfo = *pIt;
281         if (rInfo.m_aInteraction == aInteraction)
282         {
283             *pReturn = rInfo;
284             return sal_True;
285         }
286     }
287 
288     aLock.clear();
289     // <- SAFE
290 
291     return sal_False;
292 }
293 
294 } // namespace framework
295