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 #ifndef _UCBHELPER_INTERCEPTEDINTERACTION_HXX_
29 #define _UCBHELPER_INTERCEPTEDINTERACTION_HXX_
30 
31 //_______________________________________________
32 // includes
33 
34 #include <vector>
35 
36 #ifndef __COM_SUN_STAR_TASK_XINTERACTIONHANDLER_HPP__
37 #include <com/sun/star/task/XInteractionHandler.hpp>
38 #endif
39 
40 #ifndef __COM_SUN_STAR_TASK_XINTERACTIONREQUEST_HPP__
41 #include <com/sun/star/task/XInteractionRequest.hpp>
42 #endif
43 #include <cppuhelper/implbase1.hxx>
44 #include "ucbhelper/ucbhelperdllapi.h"
45 
46 //_______________________________________________
47 // namespace
48 
49 namespace ucbhelper{
50 
51 //_______________________________________________
52 // definitions
53 
54 /** @short  it wraps any other interaction handler and intercept
55             its handle() requests.
56 
57     @descr  This class can be used as:
58             - instance if special interactions must be supressed
59               only
60             - or as base class if interactions must be modified.
61  */
62 class UCBHELPER_DLLPUBLIC InterceptedInteraction : public ::cppu::WeakImplHelper1< ::com::sun::star::task::XInteractionHandler >
63 {
64     //-------------------------------------------
65     // types
66     public:
67 
68         struct InterceptedRequest
69         {
70             //-----------------------------------
71             /** @short  marks an Handle as invalid.
72              */
73             static const sal_Int32 INVALID_HANDLE = -1;
74 
75             //-----------------------------------
76             /** @short  contains the interaction request, which should be intercepted. */
77             ::com::sun::star::uno::Any Request;
78 
79             //-----------------------------------
80             /** @short  specify the fix continuation, which must be selected, if the
81                         interaction could be intercepted successfully.
82               */
83             ::com::sun::star::uno::Type Continuation;
84 
85             //-----------------------------------
86             /** @short  specify, if both interactions must have the same type
87                         or can be derived from.
88 
89                 @descr  Interaction base on exceptions - and exceptions are real types.
90                         So they can be checked in its type. These parameter "MatchExact"
91                         influence the type-check in the following way:
92                             TRUE  => the exception will be intercepted only
93                                      if it supports exactly the same type ...
94                                      or
95                             FALSE => derived exceptions will be intercepted too.
96 
97                 @attention  This parameter does not influence the check of the continuation
98                             type! The continuation must be matched exactly everytimes ...
99              */
100             sal_Bool MatchExact;
101 
102             //-----------------------------------
103             /** @short  its an unique identifier, which must be managed by the outside code.
104 
105                 @descr  If there is a derived class, which overwrites the InterceptedInteraction::intercepted()
106                         method, it will be called with a reference to an InterceptedRequest struct.
107                         Then it can use the handle to react without checking the request type again.
108              */
109             sal_Int32 Handle;
110 
111             //-----------------------------------
112             /** @short  default ctor.
113 
114                 @descr  Such constructed object cant be used realy.
115                         Might it will crash if its used!
116                         Dont forget to initialize all(!) members ...
117              */
118             InterceptedRequest()
119             {
120                 MatchExact = sal_False;
121                 Handle     = INVALID_HANDLE;
122             }
123 
124             //-----------------------------------
125             /** @short  initialize this instance.
126 
127                 @param  nHandle
128                         used to identify every intercepted request
129 
130                 @param  aRequest
131                         must contain an exception object, which can be checked
132                         in its uno-type against the later handled interaction.
133 
134                 @param  aContinuation
135                         must contain a continuation object, which is used
136                         in its uno-type to locate the same continuation
137                         inside the list of possible ones.
138 
139                 @param  bMatchExact
140                         influence the type check of the interception request.
141                         Its not used to check the continuation!
142              */
143             InterceptedRequest(      sal_Int32                    nHandle      ,
144                                const ::com::sun::star::uno::Any&  aRequest     ,
145                                const ::com::sun::star::uno::Type& aContinuation,
146                                      sal_Bool                     bMatchExact  )
147             {
148                 Handle       = nHandle;
149                 Request      = aRequest;
150                 Continuation = aContinuation;
151                 MatchExact   = bMatchExact;
152             }
153         };
154 
155         //---------------------------------------
156         /** @short  represent the different states, which can occure
157                     as result of an interception.
158 
159             @see    impl_interceptRequest()
160          */
161         enum EInterceptionState
162         {
163             /** none of the specified interceptions match the incoming request */
164             E_NOT_INTERCEPTED,
165             /** the request could be intercepted - but the specified continuation could not be located.
166                 Thats normaly an error of the programmer. May be the interaction request does not use
167                 the right set of continuations ... or the interception list contains the wrong continuation. */
168             E_NO_CONTINUATION_FOUND,
169             /** the request could be intercepted and the specified continuation could be selected successfully. */
170             E_INTERCEPTED
171         };
172 
173     //-------------------------------------------
174     // member
175     protected:
176 
177         //---------------------------------------
178         /** @short  reference to the intercepted interaction handler.
179 
180             @descr  NULL is allowed for this member!
181                     All interaction will be aborted then ...
182                     expecting th handle() was overwritten by
183                     a derived class.
184          */
185         ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler > m_xInterceptedHandler;
186 
187         //---------------------------------------
188         /** @short  these list contains the requests, which should be intercepted.
189          */
190         ::std::vector< InterceptedRequest > m_lInterceptions;
191 
192     //-------------------------------------------
193     // native interface
194     public:
195 
196         //---------------------------------------
197         /** @short  initialize a new instance with default values.
198          */
199         InterceptedInteraction();
200 
201         //---------------------------------------
202         /** @short  initialize a new instance with real values.
203 
204             @param  xInterceptedHandler
205                     the outside interaction handler, which should
206                     be intercepted here.
207 
208             @param  lInterceptions
209                     the list of intercepted requests.
210          */
211         InterceptedInteraction(const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xInterceptedHandler,
212                                const ::std::vector< InterceptedRequest >&                                             lInterceptions     );
213 
214         //---------------------------------------
215         /** @short  initialize a new instance with the interaction handler,
216                     which should be intercepted.
217 
218             @attention  If such interaction handler isnt set here,
219                         all incoming requests will be aborted ...
220                         if the right continuation is available!
221 
222             @param  xInterceptedHandler
223                     the outside interaction handler, which should
224                     be intercepted here.
225          */
226         void setInterceptedHandler(const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xInterceptedHandler);
227 
228         //---------------------------------------
229         /** @short  set a new list of intercepted interactions.
230 
231             @attention  If the interface method handle() will be overwritten by
232                         a derived class, the functionality behind these static list
233                         cant be used.
234 
235             @param  lInterceptions
236                     the list of intercepted requests.
237          */
238         void setInterceptions(const ::std::vector< InterceptedRequest >& lInterceptions);
239 
240         //---------------------------------------
241         /** @short  extract a requested continuation from te list of available ones.
242 
243             @param  lContinuations
244                     the list of available continuations.
245 
246             @param  aType
247                     is used to locate the right continuation,
248                     by checking its interface type.
249 
250             @return A valid reference to the continuation, if it could be located ...
251                     or an empty reference otherwhise.
252          */
253         static ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > extractContinuation(
254                     const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > >& lContinuations,
255                     const ::com::sun::star::uno::Type&                                                                                             aType         );
256 
257     //-------------------------------------------
258     // useable for derived classes
259     protected:
260 
261         //---------------------------------------
262         /** @short  can be overwritten by a derived class to handle interceptions
263                     outside.
264 
265             @descr  This base implementation checks, if the request could be intercepted
266                     successfully. Then this method intercepted() is called.
267                     The default implementation returns "NOT_INTERCEPTED" everytimes.
268                     So the method impl_interceptRequest() uses the right continuation automaticly.
269 
270                     If this method was overwritten and something different "NO_INTERCEPTED"
271                     is returned, the method impl_interceptRequest() will return immediatly with
272                     the result, which is returned by this intercepted() method.
273                     Then the continuations must be selected inside the intercepted() call!
274 
275             @param  rRequest
276                     it points to the intercepted request (means the item of the
277                     set interception list). e.g. its "Handle" member can be used
278                     to identify it and react very easy, without the need to check the
279                     type of the exception ...
280 
281             @param  xOrgRequest
282                     points to the original interaction, which was intercepted.
283                     It provides access to the exception and the list of possible
284                     continuations.
285 
286             @return The result of this operation.
287                     Note: If E_NOT_INTERCEPTED is returned the default handling of the base class
288                     will be used automaticly for this request!
289          */
290         virtual EInterceptionState intercepted(const InterceptedRequest&                                                             rRequest   ,
291                                                const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionRequest >& xOrgRequest);
292 
293     //-------------------------------------------
294     // uno interface
295     public:
296 
297         //---------------------------------------
298         /** @short  implements the default handling of this class ....
299                     or can be overwritten by any derived class.
300 
301             @descr  If no further class is derived from this one
302                     -> the default implementation is used. Then the
303                     internal list of requests is used to handle different
304                     interactions automaticly.
305                     (see impl_interceptRequest())
306 
307                     If this method was overwritten by a derived implementation
308                     -> the new implementation has to do everything by itself.
309                     Of course it can access all members/helpers and work with it.
310                     But the default implementation isnt used automaticly then.
311 
312             @param  xRequest
313                     the interaction request, which should be intercepted.
314          */
315         virtual void SAL_CALL handle(const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionRequest >& xRequest)
316             throw(::com::sun::star::uno::RuntimeException);
317 
318     //-------------------------------------------
319     // helper
320     private:
321 
322         //---------------------------------------
323         /** @short  implements the default handling:
324                     - intercept or forward to internal handler.
325          */
326         UCBHELPER_DLLPRIVATE void impl_handleDefault(const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionRequest >& xRequest);
327 
328         //---------------------------------------
329         /** @short  implements the interception of requests.
330 
331             @descr  The incoming request will be analyzed, if it match
332                     any request of the m_lIntercepions list.
333                     If an interception could be found, its continuation will be
334                     searched and selected.
335 
336                     The method return the state of that operation.
337                     But it doesnt call the intercepted and here set
338                     interaction handler. That has to be done in the outside method.
339 
340             @param  xRequest
341                     the interaction request, which should be intercepted.
342 
343             @return A identifier, which inidicates if the request was intercepted,
344                     the continuation was found and selected ... or not.
345          */
346         UCBHELPER_DLLPRIVATE EInterceptionState impl_interceptRequest(const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionRequest >& xRequest);
347 };
348 
349 } // namespace ucbhelper
350 
351 #endif // _UCBHELPER_INTERCEPTEDINTERACTION_HXX_
352