1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20 #include <bookmarkcontainer.hxx>
21
22 #include <osl/diagnose.h>
23 #include <comphelper/enumhelper.hxx>
24 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
25 #include <com/sun/star/lang/NoSupportException.hpp>
26 #include <cppuhelper/supportsservice.hxx>
27
28 using namespace ::com::sun::star::uno;
29 using namespace ::com::sun::star::lang;
30 using namespace ::com::sun::star::container;
31 using namespace ::osl;
32 using namespace ::comphelper;
33 using namespace ::cppu;
34
35 namespace dbaccess
36 {
37
38 // OBookmarkContainer
39
OBookmarkContainer(OWeakObject & _rParent,Mutex & _rMutex)40 OBookmarkContainer::OBookmarkContainer(OWeakObject& _rParent, Mutex& _rMutex)
41 :m_rParent(_rParent)
42 ,m_aContainerListeners(_rMutex)
43 ,m_rMutex(_rMutex)
44 {
45 }
46
47
acquire()48 void SAL_CALL OBookmarkContainer::acquire( ) noexcept
49 {
50 m_rParent.acquire();
51 }
52
release()53 void SAL_CALL OBookmarkContainer::release( ) noexcept
54 {
55 m_rParent.release();
56 }
57
~OBookmarkContainer()58 OBookmarkContainer::~OBookmarkContainer()
59 {
60 }
61
62 // XServiceInfo
getImplementationName()63 OUString SAL_CALL OBookmarkContainer::getImplementationName( )
64 {
65 return "com.sun.star.comp.dba.OBookmarkContainer";
66 }
67
supportsService(const OUString & _rServiceName)68 sal_Bool SAL_CALL OBookmarkContainer::supportsService( const OUString& _rServiceName )
69 {
70 return cppu::supportsService(this, _rServiceName);
71 }
72
getSupportedServiceNames()73 Sequence< OUString > SAL_CALL OBookmarkContainer::getSupportedServiceNames( )
74 {
75 return { "com.sun.star.sdb.DefinitionContainer" };
76 }
77
78 // XNameContainer
insertByName(const OUString & _rName,const Any & aElement)79 void SAL_CALL OBookmarkContainer::insertByName( const OUString& _rName, const Any& aElement )
80 {
81 MutexGuard aGuard(m_rMutex);
82
83 if (checkExistence(_rName))
84 throw ElementExistException();
85
86 if (_rName.isEmpty())
87 throw IllegalArgumentException();
88
89 // approve the new object
90 OUString sNewLink;
91 if (!(aElement >>= sNewLink))
92 throw IllegalArgumentException();
93
94 implAppend(_rName, sNewLink);
95
96 // notify the listeners
97 if (m_aContainerListeners.getLength())
98 {
99 ContainerEvent aEvent(*this, makeAny(_rName), makeAny(sNewLink), Any());
100 OInterfaceIteratorHelper2 aListenerIterator(m_aContainerListeners);
101 while (aListenerIterator.hasMoreElements())
102 static_cast< XContainerListener* >(aListenerIterator.next())->elementInserted(aEvent);
103 }
104 }
105
removeByName(const OUString & _rName)106 void SAL_CALL OBookmarkContainer::removeByName( const OUString& _rName )
107 {
108 OUString sOldBookmark;
109 {
110 MutexGuard aGuard(m_rMutex);
111
112 // check the arguments
113 if (_rName.isEmpty())
114 throw IllegalArgumentException();
115
116 if (!checkExistence(_rName))
117 throw NoSuchElementException();
118
119 // the old element (for the notifications)
120 sOldBookmark = m_aBookmarks[_rName];
121
122 // do the removal
123 implRemove(_rName);
124 }
125
126 // notify the listeners
127 if (m_aContainerListeners.getLength())
128 {
129 ContainerEvent aEvent(*this, makeAny(_rName), makeAny(sOldBookmark), Any());
130 OInterfaceIteratorHelper2 aListenerIterator(m_aContainerListeners);
131 while (aListenerIterator.hasMoreElements())
132 static_cast< XContainerListener* >(aListenerIterator.next())->elementRemoved(aEvent);
133 }
134 }
135
136 // XNameReplace
replaceByName(const OUString & _rName,const Any & aElement)137 void SAL_CALL OBookmarkContainer::replaceByName( const OUString& _rName, const Any& aElement )
138 {
139 ClearableMutexGuard aGuard(m_rMutex);
140
141 // check the arguments
142 if (_rName.isEmpty())
143 throw IllegalArgumentException();
144
145 // do we have such an element?
146 if (!checkExistence(_rName))
147 throw NoSuchElementException();
148
149 // approve the new object
150 OUString sNewLink;
151 if (!(aElement >>= sNewLink))
152 throw IllegalArgumentException();
153
154 // the old element (for the notifications)
155 OUString sOldLink = m_aBookmarks[_rName];
156
157 // do the replace
158 implReplace(_rName, sNewLink);
159
160 // notify the listeners
161 aGuard.clear();
162 if (m_aContainerListeners.getLength())
163 {
164 ContainerEvent aEvent(*this, makeAny(_rName), makeAny(sNewLink), makeAny(sOldLink));
165 OInterfaceIteratorHelper2 aListenerIterator(m_aContainerListeners);
166 while (aListenerIterator.hasMoreElements())
167 static_cast< XContainerListener* >(aListenerIterator.next())->elementReplaced(aEvent);
168 }
169 }
170
addContainerListener(const Reference<XContainerListener> & _rxListener)171 void SAL_CALL OBookmarkContainer::addContainerListener( const Reference< XContainerListener >& _rxListener )
172 {
173 MutexGuard aGuard(m_rMutex);
174 if (_rxListener.is())
175 m_aContainerListeners.addInterface(_rxListener);
176 }
177
removeContainerListener(const Reference<XContainerListener> & _rxListener)178 void SAL_CALL OBookmarkContainer::removeContainerListener( const Reference< XContainerListener >& _rxListener )
179 {
180 MutexGuard aGuard(m_rMutex);
181 if (_rxListener.is())
182 m_aContainerListeners.removeInterface(_rxListener);
183 }
184
185 // XElementAccess
getElementType()186 Type SAL_CALL OBookmarkContainer::getElementType( )
187 {
188 MutexGuard aGuard(m_rMutex);
189 return ::cppu::UnoType<OUString>::get();
190 }
191
hasElements()192 sal_Bool SAL_CALL OBookmarkContainer::hasElements( )
193 {
194 MutexGuard aGuard(m_rMutex);
195 return !m_aBookmarks.empty();
196 }
197
198 // XEnumerationAccess
createEnumeration()199 Reference< XEnumeration > SAL_CALL OBookmarkContainer::createEnumeration( )
200 {
201 MutexGuard aGuard(m_rMutex);
202 return new ::comphelper::OEnumerationByIndex(static_cast<XIndexAccess*>(this));
203 }
204
205 // XIndexAccess
getCount()206 sal_Int32 SAL_CALL OBookmarkContainer::getCount( )
207 {
208 MutexGuard aGuard(m_rMutex);
209 return m_aBookmarks.size();
210 }
211
getByIndex(sal_Int32 _nIndex)212 Any SAL_CALL OBookmarkContainer::getByIndex( sal_Int32 _nIndex )
213 {
214 MutexGuard aGuard(m_rMutex);
215
216 if ((_nIndex < 0) || (_nIndex >= static_cast<sal_Int32>(m_aBookmarksIndexed.size())))
217 throw IndexOutOfBoundsException();
218
219 return makeAny(m_aBookmarksIndexed[_nIndex]->second);
220 }
221
getByName(const OUString & _rName)222 Any SAL_CALL OBookmarkContainer::getByName( const OUString& _rName )
223 {
224 MutexGuard aGuard(m_rMutex);
225
226 if (!checkExistence(_rName))
227 throw NoSuchElementException();
228
229 return makeAny(m_aBookmarks[_rName]);
230 }
231
getElementNames()232 Sequence< OUString > SAL_CALL OBookmarkContainer::getElementNames( )
233 {
234 MutexGuard aGuard(m_rMutex);
235
236 Sequence< OUString > aNames(m_aBookmarks.size());
237 OUString* pNames = aNames.getArray();
238
239 for (auto const& bookmarkIndexed : m_aBookmarksIndexed)
240 {
241 *pNames = bookmarkIndexed->first;
242 ++pNames;
243 }
244
245 return aNames;
246 }
247
hasByName(const OUString & _rName)248 sal_Bool SAL_CALL OBookmarkContainer::hasByName( const OUString& _rName )
249 {
250 MutexGuard aGuard(m_rMutex);
251
252 return checkExistence(_rName);
253 }
254
implRemove(const OUString & _rName)255 void OBookmarkContainer::implRemove(const OUString& _rName)
256 {
257 MutexGuard aGuard(m_rMutex);
258
259 // look for the name in the index access vector
260 MapString2String::const_iterator aMapPos = m_aBookmarks.end();
261 auto aSearch = std::find_if(m_aBookmarksIndexed.begin(), m_aBookmarksIndexed.end(),
262 [&_rName](const MapString2String::iterator& rIter) { return rIter->first == _rName; });
263 if (aSearch != m_aBookmarksIndexed.end())
264 {
265 aMapPos = *aSearch;
266 m_aBookmarksIndexed.erase(aSearch);
267 }
268
269 if (m_aBookmarks.end() == aMapPos)
270 {
271 OSL_FAIL("OBookmarkContainer::implRemove: inconsistence!");
272 return;
273 }
274
275 // remove the map entries
276 m_aBookmarks.erase(aMapPos);
277 }
278
implAppend(const OUString & _rName,const OUString & _rDocumentLocation)279 void OBookmarkContainer::implAppend(const OUString& _rName, const OUString& _rDocumentLocation)
280 {
281 MutexGuard aGuard(m_rMutex);
282
283 OSL_ENSURE(m_aBookmarks.find(_rName) == m_aBookmarks.end(),"Bookmark already known!");
284 m_aBookmarksIndexed.push_back(m_aBookmarks.emplace( _rName,_rDocumentLocation).first);
285 }
286
implReplace(const OUString & _rName,const OUString & _rNewLink)287 void OBookmarkContainer::implReplace(const OUString& _rName, const OUString& _rNewLink)
288 {
289 MutexGuard aGuard(m_rMutex);
290 OSL_ENSURE(checkExistence(_rName), "OBookmarkContainer::implReplace : invalid name !");
291
292 m_aBookmarks[_rName] = _rNewLink;
293 }
294
getParent()295 Reference< XInterface > SAL_CALL OBookmarkContainer::getParent( )
296 {
297 return m_rParent;
298 }
299
setParent(const Reference<XInterface> &)300 void SAL_CALL OBookmarkContainer::setParent( const Reference< XInterface >& /*Parent*/ )
301 {
302 throw NoSupportException();
303 }
304
305 } // namespace dbaccess
306
307 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
308