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 #include "com/sun/star/beans/PropertyValue.hpp"
29 #include "com/sun/star/task/XInteractionRequest.hpp"
30 #include "com/sun/star/ucb/InteractiveAugmentedIOException.hpp"
31 
32 #include "ids.hrc"
33 
34 #include "iahndl.hxx"
35 
36 using namespace com::sun::star;
37 
38 namespace {
39 
40 bool
41 getStringRequestArgument(uno::Sequence< uno::Any > const & rArguments,
42                          rtl::OUString const & rKey,
43                          rtl::OUString * pValue)
44     SAL_THROW(())
45 {
46     for (sal_Int32 i = 0; i < rArguments.getLength(); ++i)
47     {
48         beans::PropertyValue aProperty;
49         if ((rArguments[i] >>= aProperty) && aProperty.Name == rKey)
50         {
51             rtl::OUString aValue;
52             if (aProperty.Value >>= aValue)
53             {
54                 if (pValue)
55                     *pValue = aValue;
56                 return true;
57             }
58         }
59     }
60     return false;
61 }
62 
63 bool
64 getBoolRequestArgument(uno::Sequence< uno::Any > const & rArguments,
65                        rtl::OUString const & rKey,
66                        bool * pValue)
67     SAL_THROW(())
68 {
69     for (sal_Int32 i = 0; i < rArguments.getLength(); ++i)
70     {
71         beans::PropertyValue aProperty;
72         if ((rArguments[i] >>= aProperty) && aProperty.Name == rKey)
73         {
74             sal_Bool bValue = sal_Bool();
75             if (aProperty.Value >>= bValue)
76             {
77                 if (pValue)
78                     *pValue = bValue;
79                 return true;
80             }
81         }
82     }
83     return false;
84 }
85 
86 bool
87 getResourceNameRequestArgument(uno::Sequence< uno::Any > const & rArguments,
88                                rtl::OUString * pValue)
89     SAL_THROW(())
90 {
91     if (!getStringRequestArgument(rArguments,
92                                   rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
93                                       "Uri")),
94                                   pValue))
95         return false;
96     // Use the resource name only for file URLs, to avoid confusion:
97     //TODO! work with ucp locality concept instead of hardcoded "file"?
98     if (pValue
99         && pValue->matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM(
100                                                   "file:")))
101         getStringRequestArgument(rArguments,
102                                  rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
103                                                    "ResourceName")),
104                                  pValue);
105     return true;
106 }
107 
108 } // namespace
109 
110 bool
111 UUIInteractionHelper::handleInteractiveIOException(
112         uno::Reference< task::XInteractionRequest > const & rRequest,
113         bool bObtainErrorStringOnly,
114         bool & bHasErrorString,
115         rtl::OUString & rErrorString)
116     SAL_THROW((uno::RuntimeException))
117 {
118     uno::Any aAnyRequest(rRequest->getRequest());
119     bHasErrorString = false;
120 
121     ucb::InteractiveIOException aIoException;
122     if (aAnyRequest >>= aIoException)
123     {
124         uno::Sequence< uno::Any > aRequestArguments;
125         ucb::InteractiveAugmentedIOException aAugmentedIoException;
126         if (aAnyRequest >>= aAugmentedIoException)
127             aRequestArguments = aAugmentedIoException.Arguments;
128 
129         ErrCode nErrorCode;
130         std::vector< rtl::OUString > aArguments;
131         static ErrCode const
132             aErrorCode[ucb::IOErrorCode_WRONG_VERSION + 1][2]
133             = { { ERRCODE_IO_ABORT, ERRCODE_UUI_IO_ABORT }, // ABORT
134                 { ERRCODE_IO_ACCESSDENIED, ERRCODE_UUI_IO_ACCESSDENIED },
135                 // ACCESS_DENIED
136                 { ERRCODE_IO_ALREADYEXISTS,
137                   ERRCODE_UUI_IO_ALREADYEXISTS }, // ALREADY_EXISTING
138                 { ERRCODE_IO_BADCRC, ERRCODE_UUI_IO_BADCRC }, // BAD_CRC
139                 { ERRCODE_IO_CANTCREATE, ERRCODE_UUI_IO_CANTCREATE },
140                 // CANT_CREATE
141                 { ERRCODE_IO_CANTREAD, ERRCODE_UUI_IO_CANTREAD },
142                 // CANT_READ
143                 { ERRCODE_IO_CANTSEEK, ERRCODE_UUI_IO_CANTSEEK },
144                 // CANT_SEEK
145                 { ERRCODE_IO_CANTTELL, ERRCODE_UUI_IO_CANTTELL },
146                 // CANT_TELL
147                 { ERRCODE_IO_CANTWRITE, ERRCODE_UUI_IO_CANTWRITE },
148                 // CANT_WRITE
149                 { ERRCODE_IO_CURRENTDIR, ERRCODE_UUI_IO_CURRENTDIR },
150                 // CURRENT_DIRECTORY
151                 { ERRCODE_IO_DEVICENOTREADY, ERRCODE_UUI_IO_NOTREADY },
152                 // DEVICE_NOT_READY
153                 { ERRCODE_IO_NOTSAMEDEVICE,
154                   ERRCODE_UUI_IO_NOTSAMEDEVICE }, // DIFFERENT_DEVICES
155                 { ERRCODE_IO_GENERAL, ERRCODE_UUI_IO_GENERAL }, // GENERAL
156                 { ERRCODE_IO_INVALIDACCESS,
157                   ERRCODE_UUI_IO_INVALIDACCESS }, // INVALID_ACCESS
158                 { ERRCODE_IO_INVALIDCHAR, ERRCODE_UUI_IO_INVALIDCHAR },
159                 // INVALID_CHARACTER
160                 { ERRCODE_IO_INVALIDDEVICE,
161                   ERRCODE_UUI_IO_INVALIDDEVICE }, // INVALID_DEVICE
162                 { ERRCODE_IO_INVALIDLENGTH,
163                   ERRCODE_UUI_IO_INVALIDLENGTH }, // INVALID_LENGTH
164                 { ERRCODE_IO_INVALIDPARAMETER,
165                   ERRCODE_UUI_IO_INVALIDPARAMETER }, // INVALID_PARAMETER
166                 { ERRCODE_IO_ISWILDCARD, ERRCODE_UUI_IO_ISWILDCARD },
167                 // IS_WILDCARD
168                 { ERRCODE_IO_LOCKVIOLATION,
169                   ERRCODE_UUI_IO_LOCKVIOLATION }, // LOCKING_VIOLATION
170                 { ERRCODE_IO_MISPLACEDCHAR,
171                   ERRCODE_UUI_IO_MISPLACEDCHAR }, // MISPLACED_CHARACTER
172                 { ERRCODE_IO_NAMETOOLONG, ERRCODE_UUI_IO_NAMETOOLONG },
173                 // NAME_TOO_LONG
174                 { ERRCODE_IO_NOTEXISTS, ERRCODE_UUI_IO_NOTEXISTS },
175                 // NOT_EXISTING
176                 { ERRCODE_IO_NOTEXISTSPATH,
177                   ERRCODE_UUI_IO_NOTEXISTSPATH }, // NOT_EXISTING_PATH
178                 { ERRCODE_IO_NOTSUPPORTED, ERRCODE_UUI_IO_NOTSUPPORTED },
179                 // NOT_SUPPORTED
180                 { ERRCODE_IO_NOTADIRECTORY,
181                   ERRCODE_UUI_IO_NOTADIRECTORY }, // NO_DIRECTORY
182                 { ERRCODE_IO_NOTAFILE, ERRCODE_UUI_IO_NOTAFILE },
183                 // NO_FILE
184                 { ERRCODE_IO_OUTOFSPACE, ERRCODE_UUI_IO_OUTOFSPACE },
185                 // OUT_OF_DISK_SPACE
186                 { ERRCODE_IO_TOOMANYOPENFILES,
187                   ERRCODE_UUI_IO_TOOMANYOPENFILES },
188                 // OUT_OF_FILE_HANDLES
189                 { ERRCODE_IO_OUTOFMEMORY, ERRCODE_UUI_IO_OUTOFMEMORY },
190                 // OUT_OF_MEMORY
191                 { ERRCODE_IO_PENDING, ERRCODE_UUI_IO_PENDING }, // PENDING
192                 { ERRCODE_IO_RECURSIVE, ERRCODE_UUI_IO_RECURSIVE },
193                 // RECURSIVE
194                 { ERRCODE_IO_UNKNOWN, ERRCODE_UUI_IO_UNKNOWN }, // UNKNOWN
195                 { ERRCODE_IO_WRITEPROTECTED,
196                   ERRCODE_UUI_IO_WRITEPROTECTED }, // WRITE_PROTECTED
197                 { ERRCODE_IO_WRONGFORMAT, ERRCODE_UUI_IO_WRONGFORMAT },
198                 // WRONG_FORMAT
199                 { ERRCODE_IO_WRONGVERSION,
200                   ERRCODE_UUI_IO_WRONGVERSION } }; // WRONG_VERSION
201         switch (aIoException.Code)
202         {
203         case ucb::IOErrorCode_CANT_CREATE:
204             {
205                 rtl::OUString aArgFolder;
206                 if (getStringRequestArgument(
207                         aRequestArguments,
208                         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
209                                           "Folder")),
210                         &aArgFolder))
211                 {
212                     rtl::OUString aArgUri;
213                     if (getResourceNameRequestArgument(aRequestArguments,
214                                                        &aArgUri))
215                     {
216                         nErrorCode = ERRCODE_UUI_IO_CANTCREATE;
217                         aArguments.reserve(2);
218                         aArguments.push_back(aArgUri);
219                         aArguments.push_back(aArgFolder);
220                     }
221                     else
222                     {
223                         nErrorCode = ERRCODE_UUI_IO_CANTCREATE_NONAME;
224                         aArguments.push_back(aArgFolder);
225                     }
226                 }
227                 else
228                     nErrorCode = aErrorCode[aIoException.Code][0];
229                 break;
230             }
231 
232         case ucb::IOErrorCode_DEVICE_NOT_READY:
233             {
234                 rtl::OUString aArgUri;
235                 if (getResourceNameRequestArgument(aRequestArguments,
236                                                    &aArgUri))
237                 {
238                     rtl::OUString aResourceType;
239                     getStringRequestArgument(
240                         aRequestArguments,
241                         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
242                                           "ResourceType")),
243                         &aResourceType);
244                     bool bRemovable = false;
245                     getBoolRequestArgument(aRequestArguments,
246                                            rtl::OUString(
247                                                RTL_CONSTASCII_USTRINGPARAM(
248                                                    "Removable")),
249                                            &bRemovable);
250                     nErrorCode
251                         = aResourceType.equalsAsciiL(
252                             RTL_CONSTASCII_STRINGPARAM("volume"))
253                         ? (bRemovable
254                            ? ERRCODE_UUI_IO_NOTREADY_VOLUME_REMOVABLE
255                            : ERRCODE_UUI_IO_NOTREADY_VOLUME)
256                         : (bRemovable
257                            ? ERRCODE_UUI_IO_NOTREADY_REMOVABLE
258                            : ERRCODE_UUI_IO_NOTREADY);
259                     aArguments.push_back(aArgUri);
260                 }
261                 else
262             nErrorCode = aErrorCode[aIoException.Code][0];
263                 break;
264             }
265 
266         case ucb::IOErrorCode_DIFFERENT_DEVICES:
267             {
268                 rtl::OUString aArgVolume;
269                 rtl::OUString aArgOtherVolume;
270                 if (getStringRequestArgument(
271                         aRequestArguments,
272                         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
273                                           "Volume")),
274                         &aArgVolume)
275                     && getStringRequestArgument(
276                         aRequestArguments,
277                         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
278                                           "OtherVolume")),
279                         &aArgOtherVolume))
280                 {
281                     nErrorCode = aErrorCode[aIoException.Code][1];
282                     aArguments.reserve(2);
283                     aArguments.push_back(aArgVolume);
284                     aArguments.push_back(aArgOtherVolume);
285                 }
286                 else
287                     nErrorCode = aErrorCode[aIoException.Code][0];
288                 break;
289         }
290 
291         case ucb::IOErrorCode_NOT_EXISTING:
292             {
293                 rtl::OUString aArgUri;
294                 if (getResourceNameRequestArgument(aRequestArguments,
295                            &aArgUri))
296                 {
297                     rtl::OUString aResourceType;
298                     getStringRequestArgument(
299                         aRequestArguments,
300                         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
301                                           "ResourceType")),
302                         &aResourceType);
303                     nErrorCode
304                         = aResourceType.equalsAsciiL(
305                             RTL_CONSTASCII_STRINGPARAM("volume"))
306                         ? ERRCODE_UUI_IO_NOTEXISTS_VOLUME
307                         : (aResourceType.equalsAsciiL(
308                                RTL_CONSTASCII_STRINGPARAM("folder"))
309                            ? ERRCODE_UUI_IO_NOTEXISTS_FOLDER
310                            : ERRCODE_UUI_IO_NOTEXISTS);
311                     aArguments.push_back(aArgUri);
312                 }
313                 else
314                     nErrorCode = aErrorCode[aIoException.Code][0];
315                 break;
316             }
317 
318         default:
319             {
320                 rtl::OUString aArgUri;
321                 if (getResourceNameRequestArgument(aRequestArguments,
322                                                    &aArgUri))
323                 {
324                     nErrorCode = aErrorCode[aIoException.Code][1];
325                     aArguments.push_back(aArgUri);
326                 }
327                 else
328                     nErrorCode = aErrorCode[aIoException.Code][0];
329                 break;
330             }
331         }
332 
333         handleErrorHandlerRequest(aIoException.Classification,
334                                   nErrorCode,
335                                   aArguments,
336                                   rRequest->getContinuations(),
337                                   bObtainErrorStringOnly,
338                                   bHasErrorString,
339                                   rErrorString);
340         return true;
341     }
342     return false;
343 }
344