/* -*- 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 .
*/
// If we found an already open storage ... we must increase // its use count. Otherwise it will may be closed too early :-)
TPath2StorageInfo::iterator pCheck = m_lStorages.find(sCheckPath);
TStorageInfo* pInfo = nullptr; if (pCheck != m_lStorages.end())
{
pInfo = &(pCheck->second);
++(pInfo->UseCount);
xChild = pInfo->Storage;
try
{
xChild = StorageHolder::openSubStorageWithFallback(xParent, lFolder, nOpenMode); // TODO think about delegating fallback decision to our own caller!
} catch(const css::uno::RuntimeException&)
{ throw; } catch(const css::uno::Exception&)
{ /* TODO URGENT! in case we found some "already existing storages" on the path before and increased its UseCount ... and now we will get an exception on creating a new sub storage ... we must decrease all UseCounts, which was touched before. Otherwise these storages can't be closed!
Idea: Using of another structure member "PossibleUseCount" as vector of unique numbers. Every thread use another unique number to identify all "owned candidates". A flush method with the same unique number force increasing of the "UseCount" variable then inside a synchronized block ...
*/ throw;
}
// TODO think about return last storage as working storage ... but don't caching it inside this holder! // => otherwise the same storage is may be commit more than once.
TPath2StorageInfo::iterator pCheck = m_lStorages.find(sCheckPath); if (pCheck == m_lStorages.end())
{ // at least one path element was not found // Seems that this path isn't open ...
lStoragesOfPath.clear(); return lStoragesOfPath;
}
css::uno::Reference< css::embed::XTransactedObject > xCommit;
StorageHolder::TStorageList::reverse_iterator pIt; for ( pIt = lStorages.rbegin(); // order of commit is important ... otherwise changes are not recognized!
pIt != lStorages.rend();
++pIt )
{
xCommit.set(*pIt, css::uno::UNO_QUERY); if (!xCommit.is()) continue;
xCommit->commit();
}
css::uno::Reference< css::embed::XStorage > StorageHolder::openSubStorageWithFallback(const css::uno::Reference< css::embed::XStorage >& xBaseStorage , const OUString& sSubStorage ,
sal_Int32 eOpenMode)
{ // a) try it first with user specified open mode // ignore errors ... but save it for later use! try
{
css::uno::Reference< css::embed::XStorage > xSubStorage = xBaseStorage->openStorageElement(sSubStorage, eOpenMode); if (xSubStorage.is()) return xSubStorage;
} catch(const css::uno::RuntimeException&)
{ throw;
} catch(const css::uno::Exception&)
{ // b) readonly already tried? => forward last error! if ((eOpenMode & css::embed::ElementModes::WRITE) != css::embed::ElementModes::WRITE) // fallback possible ? throw;
}
// b) readonly already tried, throw error if ((eOpenMode & css::embed::ElementModes::WRITE) != css::embed::ElementModes::WRITE) // fallback possible ? throw css::uno::Exception();
// c) try it readonly // don't catch exception here! Outside code wish to know, if operation failed or not. // Otherwise they work on NULL references ...
sal_Int32 eNewMode = (eOpenMode & ~css::embed::ElementModes::WRITE);
css::uno::Reference< css::embed::XStorage > xSubStorage = xBaseStorage->openStorageElement(sSubStorage, eNewMode); if (xSubStorage.is()) return xSubStorage;
// d) no chance!
SAL_INFO("fwk", "openSubStorageWithFallback(): Unexpected situation! Got no exception for missing storage ..."); return css::uno::Reference< css::embed::XStorage >();
}
OUString StorageHolder::impl_st_normPath(const OUString& sPath)
{ // path must start without "/" but end with "/"!
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.