Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <accelerators/storageholder.hxx>
30 : :
31 : : #include <threadhelp/readguard.hxx>
32 : : #include <threadhelp/writeguard.hxx>
33 : : #include <services.h>
34 : :
35 : : #include <com/sun/star/container/NoSuchElementException.hpp>
36 : :
37 : : #include <com/sun/star/container/XNameAccess.hpp>
38 : :
39 : : #include <com/sun/star/beans/XPropertySet.hpp>
40 : :
41 : : #include <com/sun/star/embed/ElementModes.hpp>
42 : :
43 : : #include <com/sun/star/embed/XTransactedObject.hpp>
44 : :
45 : : #include <com/sun/star/embed/XPackageStructureCreator.hpp>
46 : :
47 : : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
48 : :
49 : : #include <com/sun/star/io/XSeekable.hpp>
50 : :
51 : : #include <comphelper/processfactory.hxx>
52 : :
53 : :
54 : : #define PATH_SEPERATOR_ASCII "/"
55 : : #define PATH_SEPERATOR_UNICODE ((sal_Unicode)'/')
56 : : #define PATH_SEPERATOR ::rtl::OUString(PATH_SEPERATOR_ASCII)
57 : :
58 : :
59 : : namespace framework
60 : : {
61 : :
62 : : namespace css = ::com::sun::star;
63 : :
64 : : //-----------------------------------------------
65 : 0 : StorageHolder::StorageHolder()
66 : : : ThreadHelpBase( )
67 [ # # ][ # # ]: 0 : , m_xSMGR (::comphelper::getProcessServiceFactory())
68 : : {
69 : 0 : }
70 : :
71 : : //-----------------------------------------------
72 : 1798 : StorageHolder::StorageHolder(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
73 : : : ThreadHelpBase( )
74 [ + - ]: 1798 : , m_xSMGR (xSMGR)
75 : : {
76 : 1798 : }
77 : :
78 : : //-----------------------------------------------
79 [ + - ]: 1748 : StorageHolder::~StorageHolder()
80 : : {
81 : : // TODO implement me
82 : : // dispose/clear etcpp.
83 [ - + ]: 1748 : }
84 : :
85 : : //-----------------------------------------------
86 : 1558 : void StorageHolder::forgetCachedStorages()
87 : : {
88 : : // SAFE -> ----------------------------------
89 [ + - ]: 1558 : WriteGuard aWriteLock(m_aLock);
90 : :
91 : 1558 : TPath2StorageInfo::iterator pIt;
92 [ + + ][ + - ]: 5398 : for ( pIt = m_lStorages.begin();
93 : 2699 : pIt != m_lStorages.end() ;
94 : : ++pIt )
95 : : {
96 [ + - ]: 1141 : TStorageInfo& rInfo = pIt->second;
97 : : // TODO think about listener !
98 : 1141 : rInfo.Storage.clear();
99 : : }
100 [ + - ]: 1558 : m_lStorages.clear();
101 : :
102 [ + - ][ + - ]: 1558 : aWriteLock.unlock();
103 : : // <- SAFE ----------------------------------
104 : 1558 : }
105 : :
106 : : //-----------------------------------------------
107 : 1367 : void StorageHolder::setRootStorage(const css::uno::Reference< css::embed::XStorage >& xRoot)
108 : : {
109 : : // SAFE -> ----------------------------------
110 [ + - ]: 1367 : WriteGuard aWriteLock(m_aLock);
111 [ + - ]: 1367 : m_xRoot = xRoot;
112 [ + - ][ + - ]: 1367 : aWriteLock.unlock();
113 : : // <- SAFE ----------------------------------
114 : 1367 : }
115 : :
116 : : //-----------------------------------------------
117 : 1043 : css::uno::Reference< css::embed::XStorage > StorageHolder::getRootStorage() const
118 : : {
119 : : // SAFE -> ----------------------------------
120 [ + - ]: 1043 : ReadGuard aReadLock(m_aLock);
121 [ + - ]: 1043 : return m_xRoot;
122 : : // <- SAFE ----------------------------------
123 : : }
124 : :
125 : : //-----------------------------------------------
126 : 2035 : css::uno::Reference< css::embed::XStorage > StorageHolder::openPath(const ::rtl::OUString& sPath ,
127 : : sal_Int32 nOpenMode)
128 : : {
129 [ + - ]: 2035 : ::rtl::OUString sNormedPath = StorageHolder::impl_st_normPath(sPath);
130 [ + - ]: 2035 : OUStringList lFolders = StorageHolder::impl_st_parsePath(sNormedPath);
131 : :
132 : : // SAFE -> ----------------------------------
133 [ + - ]: 2035 : ReadGuard aReadLock(m_aLock);
134 : 2035 : css::uno::Reference< css::embed::XStorage > xParent = m_xRoot;
135 [ + - ]: 2035 : aReadLock.unlock();
136 : : // <- SAFE ----------------------------------
137 : :
138 : 2035 : css::uno::Reference< css::embed::XStorage > xChild ;
139 : 2035 : ::rtl::OUString sRelPath;
140 : 2035 : OUStringList::const_iterator pIt ;
141 : :
142 [ + - ][ + + ]: 11704 : for ( pIt = lFolders.begin();
[ + - ]
143 : 5852 : pIt != lFolders.end() ;
144 : : ++pIt )
145 : : {
146 : 3822 : const ::rtl::OUString& sChild = *pIt;
147 : 3822 : ::rtl::OUString sCheckPath (sRelPath);
148 : 3822 : sCheckPath += sChild;
149 : 3822 : sCheckPath += PATH_SEPERATOR;
150 : :
151 : : // SAFE -> ------------------------------
152 [ + - ]: 3822 : aReadLock.lock();
153 : :
154 : : // If we found an already open storage ... we must increase
155 : : // its use count. Otherwhise it will may be closed to early :-)
156 [ + - ]: 3822 : TPath2StorageInfo::iterator pCheck = m_lStorages.find(sCheckPath);
157 : 3822 : TStorageInfo* pInfo = 0;
158 [ + + ]: 3822 : if (pCheck != m_lStorages.end())
159 : : {
160 [ + - ]: 1263 : pInfo = &(pCheck->second);
161 : 1263 : ++(pInfo->UseCount);
162 [ + - ]: 1263 : xChild = pInfo->Storage;
163 : : }
164 : : else
165 : : {
166 [ + - ]: 2559 : aReadLock.unlock();
167 : : // <- SAFE ------------------------------
168 : :
169 : : try
170 : : {
171 [ + + ][ + - ]: 2559 : xChild = StorageHolder::openSubStorageWithFallback(xParent, sChild, nOpenMode, sal_True); // TODO think about delegating fallback decision to our own calli!
172 : : }
173 : 0 : catch(const css::uno::RuntimeException&)
174 : 0 : { throw; }
175 [ - - + ]: 10 : catch(const css::uno::Exception&)
176 : : {
177 : : /* TODO URGENT!
178 : : in case we found some "already existing storages" on the path before and increased its UseCount ...
179 : : and now we will get an exception on creating a new sub storage ...
180 : : we must decrease all UseCounts, which was touched before. Otherwise these storages cant be closed!
181 : :
182 : : Idea: Using of another structure member "PossibleUseCount" as vector of unique numbers.
183 : : Every thread use another unique number to identify all "owned candidates".
184 : : A flush method with the same unique number force increasing of the "UseCount" variable then
185 : : inside a synchronized block ...
186 : : */
187 : 5 : throw;
188 : : }
189 : :
190 : : // SAFE -> ------------------------------
191 [ + - ]: 2554 : WriteGuard aWriteLock(m_aLock);
192 [ + - ]: 2554 : pInfo = &(m_lStorages[sCheckPath]);
193 [ + - ]: 2554 : pInfo->Storage = xChild;
194 : 2554 : pInfo->UseCount = 1;
195 [ + - ][ + - ]: 2559 : aWriteLock.unlock();
196 : : // <- SAFE ------------------------------
197 : : }
198 : :
199 [ + - ]: 3817 : xParent = xChild;
200 : 3817 : sRelPath += sChild;
201 : 3817 : sRelPath += PATH_SEPERATOR;
202 : 3822 : }
203 : :
204 : : // TODO think about return last storage as working storage ... but dont caching it inside this holder!
205 : : // => otherwhise the same storage is may be commit more then once.
206 : :
207 [ + - ][ + - ]: 2035 : return xChild;
208 : : }
209 : :
210 : : //-----------------------------------------------
211 : 0 : StorageHolder::TStorageList StorageHolder::getAllPathStorages(const ::rtl::OUString& sPath)
212 : : {
213 [ # # ]: 0 : ::rtl::OUString sNormedPath = StorageHolder::impl_st_normPath(sPath);
214 [ # # ]: 0 : OUStringList lFolders = StorageHolder::impl_st_parsePath(sNormedPath);
215 : :
216 [ # # ]: 0 : StorageHolder::TStorageList lStoragesOfPath;
217 : 0 : ::rtl::OUString sRelPath ;
218 : 0 : OUStringList::const_iterator pIt ;
219 : :
220 : : // SAFE -> ----------------------------------
221 [ # # ]: 0 : ReadGuard aReadLock(m_aLock);
222 : :
223 [ # # ][ # # ]: 0 : for ( pIt = lFolders.begin();
[ # # ]
224 : 0 : pIt != lFolders.end() ;
225 : : ++pIt )
226 : : {
227 : 0 : const ::rtl::OUString& sChild = *pIt;
228 : 0 : ::rtl::OUString sCheckPath (sRelPath);
229 : 0 : sCheckPath += sChild;
230 : 0 : sCheckPath += PATH_SEPERATOR;
231 : :
232 [ # # ]: 0 : TPath2StorageInfo::iterator pCheck = m_lStorages.find(sCheckPath);
233 [ # # ]: 0 : if (pCheck == m_lStorages.end())
234 : : {
235 : : // at least one path element was not found
236 : : // Seems that this path isnt open ...
237 : 0 : lStoragesOfPath.clear();
238 : : return lStoragesOfPath;
239 : : }
240 : :
241 [ # # ]: 0 : TStorageInfo& rInfo = pCheck->second;
242 [ # # ]: 0 : lStoragesOfPath.push_back(rInfo.Storage);
243 : :
244 : 0 : sRelPath += sChild;
245 [ # # ]: 0 : sRelPath += PATH_SEPERATOR;
246 : 0 : }
247 : :
248 [ # # ]: 0 : aReadLock.unlock();
249 : : // <- SAFE ----------------------------------
250 : :
251 [ # # ][ # # ]: 0 : return lStoragesOfPath;
252 : : }
253 : :
254 : : //-----------------------------------------------
255 : 0 : void StorageHolder::commitPath(const ::rtl::OUString& sPath)
256 : : {
257 [ # # ]: 0 : StorageHolder::TStorageList lStorages = getAllPathStorages(sPath);
258 : :
259 : 0 : css::uno::Reference< css::embed::XTransactedObject > xCommit;
260 : 0 : StorageHolder::TStorageList::reverse_iterator pIt;
261 [ # # # # ]: 0 : for ( pIt = lStorages.rbegin(); // order of commit is important ... otherwhise changes are not recognized!
[ # # ]
262 : 0 : pIt != lStorages.rend() ;
263 : : ++pIt )
264 : : {
265 [ # # ][ # # ]: 0 : xCommit = css::uno::Reference< css::embed::XTransactedObject >(*pIt, css::uno::UNO_QUERY);
[ # # ]
266 [ # # ]: 0 : if (!xCommit.is())
267 : 0 : continue;
268 [ # # ][ # # ]: 0 : xCommit->commit();
269 : : }
270 : :
271 : : // SAFE -> ------------------------------
272 [ # # ]: 0 : ReadGuard aReadLock(m_aLock);
273 [ # # ][ # # ]: 0 : xCommit = css::uno::Reference< css::embed::XTransactedObject >(m_xRoot, css::uno::UNO_QUERY);
274 [ # # ]: 0 : aReadLock.unlock();
275 : : // <- SAFE ------------------------------
276 : :
277 [ # # ]: 0 : if (xCommit.is())
278 [ # # ][ # # ]: 0 : xCommit->commit();
[ # # ]
279 : 0 : }
280 : :
281 : : //-----------------------------------------------
282 : 3084 : void StorageHolder::closePath(const ::rtl::OUString& rPath)
283 : : {
284 [ + - ]: 3084 : ::rtl::OUString sNormedPath = StorageHolder::impl_st_normPath(rPath);
285 [ + - ]: 3084 : OUStringList lFolders = StorageHolder::impl_st_parsePath(sNormedPath);
286 : :
287 : : /* convert list of paths in the following way:
288 : : [0] = "path_1" => "path_1
289 : : [1] = "path_2" => "path_1/path_2"
290 : : [2] = "path_3" => "path_1/path_2/path_3"
291 : : */
292 : 3084 : OUStringList::iterator pIt1 ;
293 : 3084 : ::rtl::OUString sParentPath;
294 [ + + ][ + - ]: 15672 : for ( pIt1 = lFolders.begin();
295 : 7836 : pIt1 != lFolders.end() ;
296 : : ++pIt1 )
297 : : {
298 : 4752 : ::rtl::OUString sCurrentRelPath = sParentPath;
299 : 4752 : sCurrentRelPath += *pIt1;
300 : 4752 : sCurrentRelPath += PATH_SEPERATOR;
301 : 4752 : *pIt1 = sCurrentRelPath;
302 : 4752 : sParentPath = sCurrentRelPath;
303 : 4752 : }
304 : :
305 : : // SAFE -> ------------------------------
306 [ + - ]: 3084 : ReadGuard aReadLock(m_aLock);
307 : :
308 : 3084 : OUStringList::reverse_iterator pIt2;
309 [ + - + - ]: 15672 : for ( pIt2 = lFolders.rbegin();
[ + + ]
310 : 7836 : pIt2 != lFolders.rend() ;
311 : : ++pIt2 )
312 : : {
313 [ + - ]: 4752 : ::rtl::OUString sPath = *pIt2;
314 [ + - ]: 4752 : TPath2StorageInfo::iterator pPath = m_lStorages.find(sPath);
315 [ + + ]: 4752 : if (pPath == m_lStorages.end())
316 : 2256 : continue; // ???
317 : :
318 [ + - ]: 2496 : TStorageInfo& rInfo = pPath->second;
319 : 2496 : --rInfo.UseCount;
320 [ + + ]: 2496 : if (rInfo.UseCount < 1)
321 : : {
322 : 1313 : rInfo.Storage.clear();
323 [ + - ]: 2496 : m_lStorages.erase(pPath);
324 : : }
325 [ + + ]: 4752 : }
326 : :
327 [ + - ][ + - ]: 3084 : aReadLock.unlock();
[ + - ]
328 : : // <- SAFE ------------------------------
329 : 3084 : }
330 : :
331 : : //-----------------------------------------------
332 : 0 : void StorageHolder::notifyPath(const ::rtl::OUString& sPath)
333 : : {
334 [ # # ]: 0 : ::rtl::OUString sNormedPath = StorageHolder::impl_st_normPath(sPath);
335 : :
336 : : // SAFE -> ------------------------------
337 [ # # ]: 0 : ReadGuard aReadLock(m_aLock);
338 : :
339 [ # # ]: 0 : TPath2StorageInfo::iterator pIt1 = m_lStorages.find(sNormedPath);
340 [ # # ]: 0 : if (pIt1 == m_lStorages.end())
341 : 0 : return;
342 : :
343 [ # # ]: 0 : TStorageInfo& rInfo = pIt1->second;
344 : 0 : TStorageListenerList::iterator pIt2;
345 [ # # ][ # # ]: 0 : for ( pIt2 = rInfo.Listener.begin();
346 : 0 : pIt2 != rInfo.Listener.end() ;
347 : : ++pIt2 )
348 : : {
349 : 0 : IStorageListener* pListener = *pIt2;
350 [ # # ]: 0 : if (pListener)
351 [ # # ]: 0 : pListener->changesOccurred(sNormedPath);
352 : : }
353 : :
354 [ # # ][ # # ]: 0 : aReadLock.unlock();
[ # # ][ # # ]
355 : : // <- SAFE ------------------------------
356 : : }
357 : :
358 : : //-----------------------------------------------
359 : 1141 : void StorageHolder::addStorageListener( IStorageListener* pListener,
360 : : const ::rtl::OUString& sPath )
361 : : {
362 [ + - ]: 1141 : ::rtl::OUString sNormedPath = StorageHolder::impl_st_normPath(sPath);
363 : :
364 : : // SAFE -> ------------------------------
365 [ + - ]: 1141 : ReadGuard aReadLock(m_aLock);
366 : :
367 [ + - ]: 1141 : TPath2StorageInfo::iterator pIt1 = m_lStorages.find(sNormedPath);
368 [ - + ]: 1141 : if (pIt1 == m_lStorages.end())
369 : 1141 : return;
370 : :
371 [ + - ]: 1141 : TStorageInfo& rInfo = pIt1->second;
372 [ + - ]: 1141 : TStorageListenerList::iterator pIt2 = ::std::find(rInfo.Listener.begin(), rInfo.Listener.end(), pListener);
373 [ + - ][ + - ]: 1141 : if (pIt2 == rInfo.Listener.end())
374 [ + - ]: 1141 : rInfo.Listener.push_back(pListener);
375 : :
376 [ + - ][ + - ]: 1141 : aReadLock.unlock();
[ - + ][ + - ]
377 : : // <- SAFE ------------------------------
378 : : }
379 : :
380 : : //-----------------------------------------------
381 : 1125 : void StorageHolder::removeStorageListener( IStorageListener* pListener,
382 : : const ::rtl::OUString& sPath )
383 : : {
384 [ + - ]: 1125 : ::rtl::OUString sNormedPath = StorageHolder::impl_st_normPath(sPath);
385 : :
386 : : // SAFE -> ------------------------------
387 [ + - ]: 1125 : ReadGuard aReadLock(m_aLock);
388 : :
389 [ + - ]: 1125 : TPath2StorageInfo::iterator pIt1 = m_lStorages.find(sNormedPath);
390 [ - + ]: 1125 : if (pIt1 == m_lStorages.end())
391 : 1125 : return;
392 : :
393 [ + - ]: 1125 : TStorageInfo& rInfo = pIt1->second;
394 [ + - ]: 1125 : TStorageListenerList::iterator pIt2 = ::std::find(rInfo.Listener.begin(), rInfo.Listener.end(), pListener);
395 [ + - ][ + - ]: 1125 : if (pIt2 != rInfo.Listener.end())
396 [ + - ]: 1125 : rInfo.Listener.erase(pIt2);
397 : :
398 [ + - ][ + - ]: 1125 : aReadLock.unlock();
[ - + ][ + - ]
399 : : // <- SAFE ------------------------------
400 : : }
401 : :
402 : : //-----------------------------------------------
403 : 298 : ::rtl::OUString StorageHolder::getPathOfStorage(const css::uno::Reference< css::embed::XStorage >& xStorage)
404 : : {
405 : : // SAFE -> ------------------------------
406 [ + - ]: 298 : ReadGuard aReadLock(m_aLock);
407 : :
408 : 298 : TPath2StorageInfo::const_iterator pIt;
409 [ + + ][ + - ]: 1954 : for ( pIt = m_lStorages.begin();
410 : 977 : pIt != m_lStorages.end() ;
411 : : ++pIt )
412 : : {
413 [ + - ]: 976 : const TStorageInfo& rInfo = pIt->second;
414 [ + - ][ + + ]: 976 : if (rInfo.Storage == xStorage)
415 : 297 : break;
416 : : }
417 : :
418 [ + + ]: 298 : if (pIt == m_lStorages.end())
419 : 1 : return ::rtl::OUString();
420 : :
421 [ + - ][ + - ]: 298 : return pIt->first;
422 : :
423 : : // <- SAFE ------------------------------
424 : : }
425 : :
426 : : //-----------------------------------------------
427 : 298 : css::uno::Reference< css::embed::XStorage > StorageHolder::getParentStorage(const css::uno::Reference< css::embed::XStorage >& xChild)
428 : : {
429 [ + - ]: 298 : ::rtl::OUString sChildPath = getPathOfStorage(xChild);
430 [ + - ]: 298 : return getParentStorage(sChildPath);
431 : : }
432 : :
433 : : //-----------------------------------------------
434 : 298 : css::uno::Reference< css::embed::XStorage > StorageHolder::getParentStorage(const ::rtl::OUString& sChildPath)
435 : : {
436 : : // normed path = "a/b/c/" ... we search for "a/b/"
437 [ + - ]: 298 : ::rtl::OUString sNormedPath = StorageHolder::impl_st_normPath(sChildPath);
438 [ + - ]: 298 : OUStringList lFolders = StorageHolder::impl_st_parsePath(sNormedPath);
439 : 298 : sal_Int32 c = lFolders.size();
440 : :
441 : : // a) "" => - => no parent
442 : : // b) "a/b/c/" => "a/b/" => return storage "a/b/"
443 : : // c) "a/" => "" => return root !
444 : :
445 : : // a)
446 [ + + ]: 298 : if (c < 1)
447 : 1 : return css::uno::Reference< css::embed::XStorage >();
448 : :
449 : : // SAFE -> ----------------------------------
450 [ + - ]: 297 : ReadGuard aReadLock(m_aLock);
451 : :
452 : : // b)
453 [ - + ]: 297 : if (c < 2)
454 : 0 : return m_xRoot;
455 : :
456 : : // c)
457 : 297 : ::rtl::OUString sParentPath;
458 : 297 : sal_Int32 i = 0;
459 [ + + ]: 891 : for (i=0; i<c-1; ++i)
460 : : {
461 : 594 : sParentPath += lFolders[i];
462 : 594 : sParentPath += PATH_SEPERATOR;
463 : : }
464 : :
465 [ + - ]: 297 : TPath2StorageInfo::const_iterator pParent = m_lStorages.find(sParentPath);
466 [ + - ]: 297 : if (pParent != m_lStorages.end())
467 [ + - ]: 297 : return pParent->second.Storage;
468 : :
469 [ # # ]: 0 : aReadLock.unlock();
470 : : // <- SAFE ----------------------------------
471 : :
472 : : // ?
473 : : LOG_WARNING("StorageHolder::getParentStorage()", "Unexpected situation. Cached storage item seems to be wrong.")
474 [ + - ][ + - ]: 298 : return css::uno::Reference< css::embed::XStorage >();
475 : : }
476 : :
477 : : //-----------------------------------------------
478 : 0 : void StorageHolder::operator=(const StorageHolder& rCopy)
479 : : {
480 : : // SAFE -> ----------------------------------
481 [ # # ]: 0 : WriteGuard aWriteLock(m_aLock);
482 : :
483 [ # # ]: 0 : m_xSMGR = rCopy.m_xSMGR; // ???
484 [ # # ]: 0 : m_xRoot = rCopy.m_xRoot;
485 [ # # ]: 0 : m_lStorages = rCopy.m_lStorages;
486 : :
487 [ # # ][ # # ]: 0 : aWriteLock.unlock();
488 : : // <- SAFE ----------------------------------
489 : 0 : }
490 : :
491 : : //-----------------------------------------------
492 : 2559 : css::uno::Reference< css::embed::XStorage > StorageHolder::openSubStorageWithFallback(const css::uno::Reference< css::embed::XStorage >& xBaseStorage ,
493 : : const ::rtl::OUString& sSubStorage ,
494 : : sal_Int32 eOpenMode ,
495 : : sal_Bool bAllowFallback)
496 : : {
497 : : // a) try it first with user specified open mode
498 : : // ignore errors ... but save it for later use!
499 [ + - ]: 2559 : css::uno::Exception exResult;
500 : : try
501 : : {
502 [ + - ][ + + ]: 2559 : css::uno::Reference< css::embed::XStorage > xSubStorage = xBaseStorage->openStorageElement(sSubStorage, eOpenMode);
503 [ + - ]: 2554 : if (xSubStorage.is())
504 [ - + ]: 2554 : return xSubStorage;
505 : : }
506 : 0 : catch(const css::uno::RuntimeException&)
507 : 0 : { throw; }
508 [ - - + ]: 10 : catch(const css::uno::Exception& ex)
[ + - ]
509 [ - + ]: 5 : { exResult = ex; }
510 : :
511 : : // b) readonly already tried? => forward last error!
512 [ + - ][ + - ]: 5 : if (
513 : : (!bAllowFallback ) || // fallback allowed ?
514 : : ((eOpenMode & css::embed::ElementModes::WRITE) != css::embed::ElementModes::WRITE) // fallback possible ?
515 : : )
516 [ + - ]: 5 : throw exResult;
517 : :
518 : : // c) try it readonly
519 : : // dont catch exception here! Outside code whish to know, if operation failed or not.
520 : : // Otherwhise they work on NULL references ...
521 : 0 : sal_Int32 eNewMode = (eOpenMode & ~css::embed::ElementModes::WRITE);
522 [ # # ][ # # ]: 0 : css::uno::Reference< css::embed::XStorage > xSubStorage = xBaseStorage->openStorageElement(sSubStorage, eNewMode);
523 [ # # ]: 0 : if (xSubStorage.is())
524 : 0 : return xSubStorage;
525 : :
526 : : // d) no chance!
527 : : LOG_WARNING("openSubStorageWithFallback()", "Unexpected situation! Got no exception for missing storage ...")
528 [ + - ]: 2564 : return css::uno::Reference< css::embed::XStorage >();
529 : : }
530 : :
531 : : //-----------------------------------------------
532 : 0 : css::uno::Reference< css::io::XStream > StorageHolder::openSubStreamWithFallback(const css::uno::Reference< css::embed::XStorage >& xBaseStorage ,
533 : : const ::rtl::OUString& sSubStream ,
534 : : sal_Int32 eOpenMode ,
535 : : sal_Bool bAllowFallback)
536 : : {
537 : : // a) try it first with user specified open mode
538 : : // ignore errors ... but save it for later use!
539 [ # # ]: 0 : css::uno::Exception exResult;
540 : : try
541 : : {
542 [ # # ][ # # ]: 0 : css::uno::Reference< css::io::XStream > xSubStream = xBaseStorage->openStreamElement(sSubStream, eOpenMode);
543 [ # # ]: 0 : if (xSubStream.is())
544 [ # # ]: 0 : return xSubStream;
545 : : }
546 : 0 : catch(const css::uno::RuntimeException&)
547 : 0 : { throw; }
548 [ # # # # : 0 : catch(const css::uno::Exception& ex)
# ]
549 [ # # ]: 0 : { exResult = ex; }
550 : :
551 : : // b) readonly already tried? => forward last error!
552 [ # # ][ # # ]: 0 : if (
553 : : (!bAllowFallback ) || // fallback allowed ?
554 : : ((eOpenMode & css::embed::ElementModes::WRITE) != css::embed::ElementModes::WRITE) // fallback possible ?
555 : : )
556 [ # # ]: 0 : throw exResult;
557 : :
558 : : // c) try it readonly
559 : : // dont catch exception here! Outside code whish to know, if operation failed or not.
560 : : // Otherwhise they work on NULL references ...
561 : 0 : sal_Int32 eNewMode = (eOpenMode & ~css::embed::ElementModes::WRITE);
562 [ # # ][ # # ]: 0 : css::uno::Reference< css::io::XStream > xSubStream = xBaseStorage->openStreamElement(sSubStream, eNewMode);
563 [ # # ]: 0 : if (xSubStream.is())
564 : 0 : return xSubStream;
565 : :
566 : : // d) no chance!
567 : : LOG_WARNING("openSubStreamWithFallbacks()", "Unexpected situation! Got no exception for missing stream ...")
568 [ # # ]: 0 : return css::uno::Reference< css::io::XStream >();
569 : : }
570 : :
571 : : //-----------------------------------------------
572 : 7683 : ::rtl::OUString StorageHolder::impl_st_normPath(const ::rtl::OUString& sPath)
573 : : {
574 : : // path must start without "/" but end with "/"!
575 : :
576 : 7683 : ::rtl::OUString sNormedPath = sPath;
577 : :
578 : : // "/bla" => "bla" && "/" => "" (!)
579 [ - + ]: 7683 : if (sNormedPath.indexOf(PATH_SEPERATOR) == 0)
580 : 0 : sNormedPath += sNormedPath.copy(1);
581 : :
582 : : // "/" => "" || "" => "" ?
583 [ + + ]: 7683 : if (sNormedPath.isEmpty())
584 : 1 : return ::rtl::OUString();
585 : :
586 : : // "bla" => "bla/"
587 [ + + ]: 7682 : if (sNormedPath.lastIndexOf(PATH_SEPERATOR) != (sNormedPath.getLength()-1))
588 : 7385 : sNormedPath += PATH_SEPERATOR;
589 : :
590 : 7683 : return sNormedPath;
591 : : }
592 : :
593 : : //-----------------------------------------------
594 : 5417 : OUStringList StorageHolder::impl_st_parsePath(const ::rtl::OUString& sPath)
595 : : {
596 [ + - ]: 5417 : OUStringList lToken;
597 : 5417 : sal_Int32 i = 0;
598 : 14883 : while (sal_True)
599 : : {
600 : 14883 : ::rtl::OUString sToken = sPath.getToken(0, PATH_SEPERATOR_UNICODE, i);
601 [ + + ]: 14883 : if (i < 0)
602 : : break;
603 [ + - ][ + + ]: 24349 : lToken.push_back(sToken);
604 : 14883 : }
605 : 5417 : return lToken;
606 : : }
607 : :
608 : : //===============================================
609 : : } // namespace framework
610 : :
611 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|