summaryrefslogtreecommitdiff
path: root/ucbhelper/inc/ucbhelper/interceptedinteraction.hxx
blob: 44013b131cc0469e5a55c49c186781782ca36aac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#ifndef _UCBHELPER_INTERCEPTEDINTERACTION_HXX_
#define _UCBHELPER_INTERCEPTEDINTERACTION_HXX_

#include <vector>

#include <com/sun/star/task/XInteractionHandler.hpp>

#include <com/sun/star/task/XInteractionRequest.hpp>
#include <cppuhelper/implbase1.hxx>
#include "ucbhelper/ucbhelperdllapi.h"


namespace ucbhelper{


/** @short  it wraps any other interaction handler and intercept
            its handle() requests.

    @descr  This class can be used as:
            - instance if special interactions must be supressed
              only
            - or as base class if interactions must be modified.
 */
class UCBHELPER_DLLPUBLIC InterceptedInteraction : public ::cppu::WeakImplHelper1< ::com::sun::star::task::XInteractionHandler >
{
    //-------------------------------------------
    // types
    public:

        struct InterceptedRequest
        {
            //-----------------------------------
            /** @short  marks an Handle as invalid.
             */
            static const sal_Int32 INVALID_HANDLE = -1;

            //-----------------------------------
            /** @short  contains the interaction request, which should be intercepted. */
            ::com::sun::star::uno::Any Request;

            //-----------------------------------
            /** @short  specify the fix continuation, which must be selected, if the
                        interaction could be intercepted successfully.
              */
            ::com::sun::star::uno::Type Continuation;

            //-----------------------------------
            /** @short  specify, if both interactions must have the same type
                        or can be derived from.

                @descr  Interaction base on exceptions - and exceptions are real types.
                        So they can be checked in its type. These parameter "MatchExact"
                        influence the type-check in the following way:
                            TRUE  => the exception will be intercepted only
                                     if it supports exactly the same type ...
                                     or
                            FALSE => derived exceptions will be intercepted too.

                @attention  This parameter does not influence the check of the continuation
                            type! The continuation must be matched exactly everytimes ...
             */
            sal_Bool MatchExact;

            //-----------------------------------
            /** @short  its an unique identifier, which must be managed by the outside code.

                @descr  If there is a derived class, which overwrites the InterceptedInteraction::intercepted()
                        method, it will be called with a reference to an InterceptedRequest struct.
                        Then it can use the handle to react without checking the request type again.
             */
            sal_Int32 Handle;

            //-----------------------------------
            /** @short  default ctor.

                @descr  Such constructed object cant be used realy.
                        Might it will crash if its used!
                        Dont forget to initialize all(!) members ...
             */
            InterceptedRequest()
            {
                MatchExact = sal_False;
                Handle     = INVALID_HANDLE;
            }

            //-----------------------------------
            /** @short  initialize this instance.

                @param  nHandle
                        used to identify every intercepted request

                @param  aRequest
                        must contain an exception object, which can be checked
                        in its uno-type against the later handled interaction.

                @param  aContinuation
                        must contain a continuation object, which is used
                        in its uno-type to locate the same continuation
                        inside the list of possible ones.

                @param  bMatchExact
                        influence the type check of the interception request.
                        Its not used to check the continuation!
             */
            InterceptedRequest(      sal_Int32                    nHandle      ,
                               const ::com::sun::star::uno::Any&  aRequest     ,
                               const ::com::sun::star::uno::Type& aContinuation,
                                     sal_Bool                     bMatchExact  )
            {
                Handle       = nHandle;
                Request      = aRequest;
                Continuation = aContinuation;
                MatchExact   = bMatchExact;
            }
        };

        //---------------------------------------
        /** @short  represent the different states, which can occure
                    as result of an interception.

            @see    impl_interceptRequest()
         */
        enum EInterceptionState
        {
            /** none of the specified interceptions match the incoming request */
            E_NOT_INTERCEPTED,
            /** the request could be intercepted - but the specified continuation could not be located.
                Thats normaly an error of the programmer. May be the interaction request does not use
                the right set of continuations ... or the interception list contains the wrong continuation. */
            E_NO_CONTINUATION_FOUND,
            /** the request could be intercepted and the specified continuation could be selected successfully. */
            E_INTERCEPTED
        };

    //-------------------------------------------
    // member
    protected:

        //---------------------------------------
        /** @short  reference to the intercepted interaction handler.

            @descr  NULL is allowed for this member!
                    All interaction will be aborted then ...
                    expecting th handle() was overwritten by
                    a derived class.
         */
        ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler > m_xInterceptedHandler;

        //---------------------------------------
        /** @short  these list contains the requests, which should be intercepted.
         */
        ::std::vector< InterceptedRequest > m_lInterceptions;

    //-------------------------------------------
    // native interface
    public:

        //---------------------------------------
        /** @short  initialize a new instance with default values.
         */
        InterceptedInteraction();

        //---------------------------------------
        /** @short  initialize a new instance with real values.

            @param  xInterceptedHandler
                    the outside interaction handler, which should
                    be intercepted here.

            @param  lInterceptions
                    the list of intercepted requests.
         */
        InterceptedInteraction(const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xInterceptedHandler,
                               const ::std::vector< InterceptedRequest >&                                             lInterceptions     );

        //---------------------------------------
        /** @short  initialize a new instance with the interaction handler,
                    which should be intercepted.

            @attention  If such interaction handler isnt set here,
                        all incoming requests will be aborted ...
                        if the right continuation is available!

            @param  xInterceptedHandler
                    the outside interaction handler, which should
                    be intercepted here.
         */
        void setInterceptedHandler(const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xInterceptedHandler);

        //---------------------------------------
        /** @short  set a new list of intercepted interactions.

            @attention  If the interface method handle() will be overwritten by
                        a derived class, the functionality behind these static list
                        cant be used.

            @param  lInterceptions
                    the list of intercepted requests.
         */
        void setInterceptions(const ::std::vector< InterceptedRequest >& lInterceptions);

        //---------------------------------------
        /** @short  extract a requested continuation from te list of available ones.

            @param  lContinuations
                    the list of available continuations.

            @param  aType
                    is used to locate the right continuation,
                    by checking its interface type.

            @return A valid reference to the continuation, if it could be located ...
                    or an empty reference otherwhise.
         */
        static ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > extractContinuation(
                    const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > >& lContinuations,
                    const ::com::sun::star::uno::Type&                                                                                             aType         );

    //-------------------------------------------
    // useable for derived classes
    protected:

        //---------------------------------------
        /** @short  can be overwritten by a derived class to handle interceptions
                    outside.

            @descr  This base implementation checks, if the request could be intercepted
                    successfully. Then this method intercepted() is called.
                    The default implementation returns "NOT_INTERCEPTED" everytimes.
                    So the method impl_interceptRequest() uses the right continuation automaticly.

                    If this method was overwritten and something different "NO_INTERCEPTED"
                    is returned, the method impl_interceptRequest() will return immediatly with
                    the result, which is returned by this intercepted() method.
                    Then the continuations must be selected inside the intercepted() call!

            @param  rRequest
                    it points to the intercepted request (means the item of the
                    set interception list). e.g. its "Handle" member can be used
                    to identify it and react very easy, without the need to check the
                    type of the exception ...

            @param  xOrgRequest
                    points to the original interaction, which was intercepted.
                    It provides access to the exception and the list of possible
                    continuations.

            @return The result of this operation.
                    Note: If E_NOT_INTERCEPTED is returned the default handling of the base class
                    will be used automaticly for this request!
         */
        virtual EInterceptionState intercepted(const InterceptedRequest&                                                             rRequest   ,
                                               const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionRequest >& xOrgRequest);

    //-------------------------------------------
    // uno interface
    public:

        //---------------------------------------
        /** @short  implements the default handling of this class ....
                    or can be overwritten by any derived class.

            @descr  If no further class is derived from this one
                    -> the default implementation is used. Then the
                    internal list of requests is used to handle different
                    interactions automaticly.
                    (see impl_interceptRequest())

                    If this method was overwritten by a derived implementation
                    -> the new implementation has to do everything by itself.
                    Of course it can access all members/helpers and work with it.
                    But the default implementation isnt used automaticly then.

            @param  xRequest
                    the interaction request, which should be intercepted.
         */
        virtual void SAL_CALL handle(const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionRequest >& xRequest)
            throw(::com::sun::star::uno::RuntimeException);

    //-------------------------------------------
    // helper
    private:

        //---------------------------------------
        /** @short  implements the default handling:
                    - intercept or forward to internal handler.
         */
        UCBHELPER_DLLPRIVATE void impl_handleDefault(const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionRequest >& xRequest);

        //---------------------------------------
        /** @short  implements the interception of requests.

            @descr  The incoming request will be analyzed, if it match
                    any request of the m_lIntercepions list.
                    If an interception could be found, its continuation will be
                    searched and selected.

                    The method return the state of that operation.
                    But it doesnt call the intercepted and here set
                    interaction handler. That has to be done in the outside method.

            @param  xRequest
                    the interaction request, which should be intercepted.

            @return A identifier, which inidicates if the request was intercepted,
                    the continuation was found and selected ... or not.
         */
        UCBHELPER_DLLPRIVATE EInterceptionState impl_interceptRequest(const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionRequest >& xRequest);
};

} // namespace ucbhelper

#endif // _UCBHELPER_INTERCEPTEDINTERACTION_HXX_

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */