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