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_ucbhelper.hxx"
30 #include <ucbhelper/interceptedinteraction.hxx>
31 
32 //_______________________________________________
33 // includes
34 
35 //_______________________________________________
36 // namespace
37 
38 namespace ucbhelper{
39 
40 namespace css = ::com::sun::star;
41 
42 //_______________________________________________
43 // definitions
44 
45 /*-----------------------------------------------
46     17.03.2004 11:00
47 -----------------------------------------------*/
48 InterceptedInteraction::InterceptedInteraction()
49 {
50 }
51 
52 /*-----------------------------------------------
53     17.03.2004 14:55
54 -----------------------------------------------*/
55 void InterceptedInteraction::setInterceptedHandler(const css::uno::Reference< css::task::XInteractionHandler >& xInterceptedHandler)
56 {
57     m_xInterceptedHandler = xInterceptedHandler;
58 }
59 
60 /*-----------------------------------------------
61     17.03.2004 14:55
62 -----------------------------------------------*/
63 void InterceptedInteraction::setInterceptions(const ::std::vector< InterceptedRequest >& lInterceptions)
64 {
65     m_lInterceptions = lInterceptions;
66 }
67 
68 /*-----------------------------------------------
69     18.03.2004 10:10
70 -----------------------------------------------*/
71 InterceptedInteraction::EInterceptionState InterceptedInteraction::intercepted(
72     const InterceptedRequest&,
73     const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionRequest >&)
74 {
75     // default behaviour! see impl_interceptRequest() for further informations ...
76     return E_NOT_INTERCEPTED;
77 }
78 
79 /*-----------------------------------------------
80     18.03.2004 09:46
81 -----------------------------------------------*/
82 css::uno::Reference< css::task::XInteractionContinuation > InterceptedInteraction::extractContinuation(const css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > >& lContinuations,
83                                                                                                        const css::uno::Type&                                                                   aType         )
84 {
85     const css::uno::Reference< css::task::XInteractionContinuation >* pContinuations = lContinuations.getConstArray();
86 
87     sal_Int32 c = lContinuations.getLength();
88     sal_Int32 i = 0;
89 
90     for (i=0; i<c; ++i)
91     {
92         css::uno::Reference< css::uno::XInterface > xCheck(pContinuations[i], css::uno::UNO_QUERY);
93         if (xCheck->queryInterface(aType).hasValue())
94             return pContinuations[i];
95     }
96 
97     return css::uno::Reference< css::task::XInteractionContinuation >();
98 }
99 
100 /*-----------------------------------------------
101     18.03.2004 10:03
102 -----------------------------------------------*/
103 void SAL_CALL InterceptedInteraction::handle(const css::uno::Reference< css::task::XInteractionRequest >& xRequest)
104     throw(css::uno::RuntimeException)
105 {
106     impl_handleDefault(xRequest);
107 }
108 
109 /*-----------------------------------------------
110     18.03.2004 10:02
111 -----------------------------------------------*/
112 void InterceptedInteraction::impl_handleDefault(const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionRequest >& xRequest)
113 {
114     EInterceptionState eState = impl_interceptRequest(xRequest);
115 
116     switch(eState)
117     {
118         case E_NOT_INTERCEPTED:
119         {
120             // Non of the intercepted requests match to the given one.
121             // => forward request to the internal wrapped handler - if there is one.
122             if (m_xInterceptedHandler.is())
123                 m_xInterceptedHandler->handle(xRequest);
124         }
125         break;
126 
127         case E_NO_CONTINUATION_FOUND:
128         {
129             // Runtime error! The defined continuation could not be located
130             // inside the set of available containuations of the incoming request.
131             // Whats wrong - the interception list or the request?
132             OSL_ENSURE(sal_False, "InterceptedInteraction::handle()\nCould intercept this interaction request - but cant locate the right continuation!");
133         }
134         break;
135 
136         case E_INTERCEPTED:
137         break;
138     }
139 }
140 
141 /*-----------------------------------------------
142     18.03.2004 09:48
143 -----------------------------------------------*/
144 InterceptedInteraction::EInterceptionState InterceptedInteraction::impl_interceptRequest(const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionRequest >& xRequest)
145 {
146     css::uno::Any                                                                    aRequest       = xRequest->getRequest();
147     css::uno::Type                                                                   aRequestType   = aRequest.getValueType();
148     css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > lContinuations = xRequest->getContinuations();
149 
150     // check against the list of static requests
151     sal_Int32 nHandle = 0;
152     ::std::vector< InterceptedRequest >::const_iterator pIt;
153     for (  pIt  = m_lInterceptions.begin();
154            pIt != m_lInterceptions.end()  ;
155          ++pIt                            )
156     {
157         const InterceptedRequest& rInterception = *pIt;
158         css::uno::Type aInterceptedType = rInterception.Request.getValueType();
159 
160         // check the request
161         sal_Bool bMatch = sal_False;
162         if (rInterception.MatchExact)
163             bMatch = aInterceptedType.equals(aRequestType);
164         else
165             bMatch = aInterceptedType.isAssignableFrom(aRequestType); // dont change intercepted and request type here -> it will check the wrong direction!
166 
167         // intercepted ...
168         // Call they might existing derived class, so they can handle that by its own.
169         // If its not interested on that (may be its not overwritten and the default implementation
170         // returns E_NOT_INTERCEPTED as default) -> break this loop and search for the right continuation.
171         if (bMatch)
172         {
173             EInterceptionState eState = intercepted(rInterception, xRequest);
174             if (eState == E_NOT_INTERCEPTED)
175                 break;
176             return eState;
177         }
178 
179         ++nHandle;
180     }
181 
182     if (pIt != m_lInterceptions.end()) // => can be true only if bMatch=TRUE!
183     {
184         // match -> search required continuation
185         const InterceptedRequest& rInterception = *pIt;
186         css::uno::Reference< css::task::XInteractionContinuation > xContinuation = InterceptedInteraction::extractContinuation(lContinuations, rInterception.Continuation);
187         if (xContinuation.is())
188         {
189             xContinuation->select();
190             return E_INTERCEPTED;
191         }
192 
193         // Can be reached only, if the request does not support the given continuation!
194         // => RuntimeError!?
195         return E_NO_CONTINUATION_FOUND;
196     }
197 
198     return E_NOT_INTERCEPTED;
199 }
200 
201 } // namespace ucbhelper
202