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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_comphelper.hxx"
26 #include <comphelper/stillreadwriteinteraction.hxx>
27
28 #ifndef __COM_SUN_STAR_UCB_INTERACTIVEIOEXCEPTION_HPP__
29 #include <com/sun/star/ucb/InteractiveIOException.hpp>
30 #endif
31
32 #ifndef __COM_SUN_STAR_TASK_XINTERACTIONABORT_HPP__
33 #include <com/sun/star/task/XInteractionAbort.hpp>
34 #endif
35
36 #ifndef __COM_SUN_STAR_UCB_UNSUPPORTEDDATASINKEXCEPTION_HPP__
37 #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
38 #endif
39
40 #include <com/sun/star/ucb/AuthenticationRequest.hpp>
41
42 namespace comphelper{
43
44 namespace css = ::com::sun::star;
45
StillReadWriteInteraction(const css::uno::Reference<css::task::XInteractionHandler> & xHandler,const css::uno::Reference<css::task::XInteractionHandler> & xAuthenticationHandler)46 StillReadWriteInteraction::StillReadWriteInteraction(const css::uno::Reference< css::task::XInteractionHandler >& xHandler,
47 const css::uno::Reference< css::task::XInteractionHandler >& xAuthenticationHandler)
48 : m_bUsed (sal_False)
49 , m_bHandledByMySelf (sal_False)
50 , m_bHandledByInternalHandler(sal_False)
51 , m_xAuthenticationHandler(xAuthenticationHandler)
52 {
53 ::std::vector< ::ucbhelper::InterceptedInteraction::InterceptedRequest > lInterceptions;
54 ::ucbhelper::InterceptedInteraction::InterceptedRequest aInterceptedRequest;
55
56 aInterceptedRequest.Handle = HANDLE_INTERACTIVEIOEXCEPTION;
57 aInterceptedRequest.Request <<= css::ucb::InteractiveIOException();
58 aInterceptedRequest.Continuation = ::getCppuType(static_cast< css::uno::Reference< css::task::XInteractionAbort >* >(0));
59 aInterceptedRequest.MatchExact = sal_False;
60 lInterceptions.push_back(aInterceptedRequest);
61
62 aInterceptedRequest.Handle = HANDLE_UNSUPPORTEDDATASINKEXCEPTION;
63 aInterceptedRequest.Request <<= css::ucb::UnsupportedDataSinkException();
64 aInterceptedRequest.Continuation = ::getCppuType(static_cast< css::uno::Reference< css::task::XInteractionAbort >* >(0));
65 aInterceptedRequest.MatchExact = sal_False;
66 lInterceptions.push_back(aInterceptedRequest);
67
68 aInterceptedRequest.Handle = HANDLE_AUTHENTICATIONREQUESTEXCEPTION;
69 aInterceptedRequest.Request <<= css::ucb::AuthenticationRequest();
70 aInterceptedRequest.Continuation = ::getCppuType(static_cast< css::uno::Reference< css::task::XInteractionAbort >* >(0));
71 aInterceptedRequest.MatchExact = sal_False;
72 lInterceptions.push_back(aInterceptedRequest);
73
74 setInterceptedHandler(xHandler);
75 setInterceptions(lInterceptions);
76 }
77
resetInterceptions()78 void StillReadWriteInteraction::resetInterceptions()
79 {
80 setInterceptions(::std::vector< ::ucbhelper::InterceptedInteraction::InterceptedRequest >());
81 }
82
resetErrorStates()83 void StillReadWriteInteraction::resetErrorStates()
84 {
85 m_bUsed = sal_False;
86 m_bHandledByMySelf = sal_False;
87 m_bHandledByInternalHandler = sal_False;
88 }
89
wasWriteError()90 sal_Bool StillReadWriteInteraction::wasWriteError()
91 {
92 return (m_bUsed && m_bHandledByMySelf);
93 }
94
intercepted(const::ucbhelper::InterceptedInteraction::InterceptedRequest & aRequest,const::com::sun::star::uno::Reference<::com::sun::star::task::XInteractionRequest> & xRequest)95 ucbhelper::InterceptedInteraction::EInterceptionState StillReadWriteInteraction::intercepted(const ::ucbhelper::InterceptedInteraction::InterceptedRequest& aRequest,
96 const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionRequest >& xRequest)
97 {
98 // we are used!
99 m_bUsed = sal_True;
100
101 // check if its a real interception - might some parameters are not the right ones ...
102 sal_Bool bAbort = sal_False;
103 switch(aRequest.Handle)
104 {
105 case HANDLE_INTERACTIVEIOEXCEPTION:
106 {
107 css::ucb::InteractiveIOException exIO;
108 xRequest->getRequest() >>= exIO;
109 bAbort = (
110 (exIO.Code == css::ucb::IOErrorCode_ACCESS_DENIED )
111 || (exIO.Code == css::ucb::IOErrorCode_LOCKING_VIOLATION )
112 || (exIO.Code == css::ucb::IOErrorCode_NOT_EXISTING )
113 #ifdef MACOSX
114 // this is a workaround for MAC, on this platform if the file is locked
115 // the returned error code looks to be wrong
116 || (exIO.Code == css::ucb::IOErrorCode_GENERAL )
117 #endif
118 );
119 }
120 break;
121
122 case HANDLE_UNSUPPORTEDDATASINKEXCEPTION:
123 {
124 bAbort = sal_True;
125 }
126 break;
127 case HANDLE_AUTHENTICATIONREQUESTEXCEPTION:
128 {
129 //use internal authentication dedicated handler and return
130 if (m_xAuthenticationHandler.is())
131 {
132 m_xAuthenticationHandler->handle(xRequest);
133 return ::ucbhelper::InterceptedInteraction::E_INTERCEPTED;
134 }
135 else //simply abort
136 bAbort = sal_True;;
137 }
138 break;
139 }
140
141 // handle interaction by ourself
142 if (bAbort)
143 {
144 m_bHandledByMySelf = sal_True;
145 css::uno::Reference< css::task::XInteractionContinuation > xAbort = ::ucbhelper::InterceptedInteraction::extractContinuation(
146 xRequest->getContinuations(),
147 ::getCppuType(static_cast< css::uno::Reference< css::task::XInteractionAbort >* >(0)));
148 if (!xAbort.is())
149 return ::ucbhelper::InterceptedInteraction::E_NO_CONTINUATION_FOUND;
150 xAbort->select();
151 return ::ucbhelper::InterceptedInteraction::E_INTERCEPTED;
152 }
153
154 // Otherwise use internal handler.
155 if (m_xInterceptedHandler.is())
156 {
157 m_bHandledByInternalHandler = sal_True;
158 m_xInterceptedHandler->handle(xRequest);
159 }
160 return ::ucbhelper::InterceptedInteraction::E_INTERCEPTED;
161 }
162 }
163