bump product version to 7.2.5.1
[LibreOffice.git] / connectivity / source / drivers / hsqldb / HStorageMap.cxx
blob63b5e0481c5cf6fa438eefeac2278cd22d25b1b0
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <hsqldb/HStorageMap.hxx>
21 #include <comphelper/types.hxx>
22 #include <com/sun/star/embed/XTransactionBroadcaster.hpp>
23 #include <com/sun/star/embed/XTransactedObject.hpp>
24 #include <com/sun/star/embed/ElementModes.hpp>
25 #include <com/sun/star/lang/DisposedException.hpp>
26 #include <osl/diagnose.h>
27 #include <sal/log.hxx>
28 #include <uno/mapping.hxx>
29 #include <algorithm>
30 #include <tools/diagnose_ex.h>
32 namespace connectivity::hsqldb
35 using namespace ::com::sun::star::uno;
36 using namespace ::com::sun::star::lang;
37 using namespace ::com::sun::star::embed;
38 using namespace ::com::sun::star::io;
40 StreamHelper::StreamHelper(const Reference< XStream>& _xStream)
41 : m_xStream(_xStream)
45 StreamHelper::~StreamHelper()
47 try
49 m_xStream.clear();
50 m_xSeek.clear();
51 if ( m_xInputStream.is() )
53 m_xInputStream->closeInput();
54 m_xInputStream.clear();
56 // this is done implicitly by the closing of the input stream
57 else if ( m_xOutputStream.is() )
59 m_xOutputStream->closeOutput();
60 try
62 ::comphelper::disposeComponent(m_xOutputStream);
64 catch(const DisposedException&)
67 catch(const Exception&)
69 OSL_FAIL("Could not dispose OutputStream");
71 m_xOutputStream.clear();
74 catch(const Exception&)
76 TOOLS_WARN_EXCEPTION( "connectivity.hsqldb", "");
80 Reference< XInputStream> const & StreamHelper::getInputStream()
82 if ( !m_xInputStream.is() )
83 m_xInputStream = m_xStream->getInputStream();
84 return m_xInputStream;
87 Reference< XOutputStream> const & StreamHelper::getOutputStream()
89 if ( !m_xOutputStream.is() )
90 m_xOutputStream = m_xStream->getOutputStream();
91 return m_xOutputStream;
94 Reference< XSeekable> const & StreamHelper::getSeek()
96 if ( !m_xSeek.is() )
97 m_xSeek.set(m_xStream,UNO_QUERY);
98 return m_xSeek;
101 css::uno::Reference<css::embed::XStorage> StorageData::mapStorage()
102 const
104 css::uno::Environment env(css::uno::Environment::getCurrent());
105 if (!(env.is() && storageEnvironment.is())) {
106 throw css::uno::RuntimeException("cannot get environments");
108 if (env.get() == storageEnvironment.get()) {
109 return storage;
110 } else {
111 css::uno::Mapping map(storageEnvironment, env);
112 if (!map.is()) {
113 throw css::uno::RuntimeException("cannot get mapping");
115 css::uno::Reference<css::embed::XStorage> mapped;
116 map.mapInterface(
117 reinterpret_cast<void **>(&mapped), storage.get(),
118 cppu::UnoType<css::embed::XStorage>::get());
119 return mapped;
123 static TStorages& lcl_getStorageMap()
125 static TStorages s_aMap;
126 return s_aMap;
129 static OUString lcl_getNextCount()
131 static sal_Int32 s_nCount = 0;
132 return OUString::number(s_nCount++);
135 OUString StorageContainer::removeURLPrefix(const OUString& _sURL,const OUString& _sFileURL)
137 return _sURL.copy(_sFileURL.getLength()+1);
140 OUString StorageContainer::removeOldURLPrefix(const OUString& _sURL)
142 OUString sRet = _sURL;
143 #if defined(_WIN32)
144 sal_Int32 nIndex = sRet.lastIndexOf('\\');
145 #else
146 sal_Int32 nIndex = sRet.lastIndexOf('/');
147 #endif
148 if ( nIndex != -1 )
150 sRet = _sURL.copy(nIndex+1);
152 return sRet;
155 /*****************************************************************************/
156 /* convert jstring to rtl_uString */
158 OUString StorageContainer::jstring2ustring(JNIEnv * env, jstring jstr)
160 if (env->ExceptionCheck())
162 env->ExceptionClear();
163 OSL_FAIL("ExceptionClear");
165 OUString aStr;
166 if ( jstr )
168 jboolean bCopy(true);
169 const jchar* pChar = env->GetStringChars(jstr,&bCopy);
170 jsize len = env->GetStringLength(jstr);
171 aStr = OUString(
172 reinterpret_cast<sal_Unicode const *>(pChar), len);
174 if(bCopy)
175 env->ReleaseStringChars(jstr,pChar);
178 if (env->ExceptionCheck())
180 env->ExceptionClear();
181 OSL_FAIL("ExceptionClear");
183 return aStr;
187 OUString StorageContainer::registerStorage(const Reference< XStorage>& _xStorage,const OUString& _sURL)
189 OSL_ENSURE(_xStorage.is(),"Storage is NULL!");
190 TStorages& rMap = lcl_getStorageMap();
191 // check if the storage is already in our map
192 TStorages::const_iterator aFind = std::find_if(rMap.begin(),rMap.end(),
193 [&_xStorage] (const TStorages::value_type& storage) {
194 return storage.second.mapStorage() == _xStorage;
197 if ( aFind == rMap.end() )
199 aFind = rMap.insert(TStorages::value_type(lcl_getNextCount(), {_xStorage, css::uno::Environment::getCurrent(), _sURL, TStreamMap()})).first;
202 return aFind->first;
205 TStorages::mapped_type StorageContainer::getRegisteredStorage(const OUString& _sKey)
207 TStorages::mapped_type aRet;
208 TStorages& rMap = lcl_getStorageMap();
209 TStorages::const_iterator aFind = rMap.find(_sKey);
210 OSL_ENSURE(aFind != rMap.end(),"Storage could not be found in list!");
211 if ( aFind != rMap.end() )
212 aRet = aFind->second;
214 return aRet;
217 OUString StorageContainer::getRegisteredKey(const Reference< XStorage>& _xStorage)
219 OUString sKey;
220 OSL_ENSURE(_xStorage.is(),"Storage is NULL!");
221 TStorages& rMap = lcl_getStorageMap();
222 // check if the storage is already in our map
223 TStorages::const_iterator aFind = std::find_if(rMap.begin(),rMap.end(),
224 [&_xStorage] (const TStorages::value_type& storage) {
225 return storage.second.mapStorage() == _xStorage;
228 if ( aFind != rMap.end() )
229 sKey = aFind->first;
230 return sKey;
233 void StorageContainer::revokeStorage(const OUString& _sKey,const Reference<XTransactionListener>& _xListener)
235 TStorages& rMap = lcl_getStorageMap();
236 TStorages::iterator aFind = rMap.find(_sKey);
237 if ( aFind == rMap.end() )
238 return;
242 if ( _xListener.is() )
244 Reference<XTransactionBroadcaster> xBroad(aFind->second.mapStorage(),UNO_QUERY);
245 if ( xBroad.is() )
246 xBroad->removeTransactionListener(_xListener);
247 Reference<XTransactedObject> xTrans(aFind->second.mapStorage(),UNO_QUERY);
248 if ( xTrans.is() )
249 xTrans->commit();
252 catch(const Exception&)
255 rMap.erase(aFind);
258 TStreamMap::mapped_type StorageContainer::registerStream(JNIEnv * env,jstring name, jstring key,sal_Int32 _nMode)
260 TStreamMap::mapped_type pHelper;
261 TStorages& rMap = lcl_getStorageMap();
262 OUString sKey = jstring2ustring(env,key);
263 TStorages::iterator aFind = rMap.find(sKey);
264 OSL_ENSURE(aFind != rMap.end(),"Storage could not be found in list!");
265 if ( aFind != rMap.end() )
267 TStorages::mapped_type aStoragePair = StorageContainer::getRegisteredStorage(sKey);
268 auto storage = aStoragePair.mapStorage();
269 OSL_ENSURE(storage.is(),"No Storage available!");
270 if ( storage.is() )
272 OUString sOrgName = StorageContainer::jstring2ustring(env,name);
273 OUString sName = removeURLPrefix(sOrgName,aStoragePair.url);
274 TStreamMap::iterator aStreamFind = aFind->second.streams.find(sName);
275 OSL_ENSURE( aStreamFind == aFind->second.streams.end(),"A Stream was already registered for this object!");
276 if ( aStreamFind != aFind->second.streams.end() )
278 pHelper = aStreamFind->second;
280 else
286 pHelper = std::make_shared<StreamHelper>(storage->openStreamElement(sName,_nMode));
288 catch(const Exception&)
290 OUString sStrippedName = removeOldURLPrefix(sOrgName);
292 if ( (_nMode & ElementModes::WRITE) != ElementModes::WRITE )
294 bool bIsStream = true;
297 bIsStream = storage->isStreamElement(sStrippedName);
299 catch(const Exception&)
301 bIsStream = false;
303 if ( !bIsStream )
304 return pHelper; // readonly file without data stream
306 pHelper = std::make_shared<StreamHelper>(storage->openStreamElement( sStrippedName, _nMode ) );
308 aFind->second.streams.emplace(sName,pHelper);
310 catch(const Exception& e)
312 TOOLS_WARN_EXCEPTION( "connectivity.hsqldb", "[HSQLDB-SDBC] caught an exception while opening a stream\n"
313 "Name: " << sName
314 << "\nMode: 0x" << ( _nMode < 16 ? "0" : "")
315 << std::hex << _nMode );
316 StorageContainer::throwJavaException(e,env);
321 return pHelper;
324 void StorageContainer::revokeStream( JNIEnv * env,jstring name, jstring key)
326 TStorages& rMap = lcl_getStorageMap();
327 TStorages::iterator aFind = rMap.find(jstring2ustring(env,key));
328 OSL_ENSURE(aFind != rMap.end(),"Storage could not be found in list!");
329 if ( aFind != rMap.end() )
330 aFind->second.streams.erase(removeURLPrefix(jstring2ustring(env,name),aFind->second.url));
333 TStreamMap::mapped_type StorageContainer::getRegisteredStream( JNIEnv * env,jstring name, jstring key)
335 TStreamMap::mapped_type pRet;
336 TStorages& rMap = lcl_getStorageMap();
337 TStorages::const_iterator aFind = rMap.find(jstring2ustring(env,key));
338 OSL_ENSURE(aFind != rMap.end(),"Storage could not be found in list!");
339 if ( aFind != rMap.end() )
341 TStreamMap::const_iterator aStreamFind = aFind->second.streams.find(removeURLPrefix(jstring2ustring(env,name),aFind->second.url));
342 if ( aStreamFind != aFind->second.streams.end() )
343 pRet = aStreamFind->second;
346 return pRet;
349 void StorageContainer::throwJavaException(const Exception& _aException,JNIEnv * env)
351 if (env->ExceptionCheck())
352 env->ExceptionClear();
353 SAL_WARN("connectivity.hsqldb", "forwarding Exception: " << _aException );
354 OString cstr( OUStringToOString(_aException.Message, RTL_TEXTENCODING_JAVA_UTF8 ) );
355 env->ThrowNew(env->FindClass("java/io/IOException"), cstr.getStr());
358 } // namespace
361 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */