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 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_dbaccess.hxx"
30 
31 #ifndef _DBA_CORE_BOOKMARKCONTAINER_HXX_
32 #include "bookmarkcontainer.hxx"
33 #endif
34 #ifndef DBACCESS_SHARED_DBASTRINGS_HRC
35 #include "dbastrings.hrc"
36 #endif
37 #ifndef _DBASHARED_APITOOLS_HXX_
38 #include "apitools.hxx"
39 #endif
40 #ifndef _DBA_CORE_RESOURCE_HXX_
41 #include "core_resource.hxx"
42 #endif
43 #ifndef _DBA_CORE_RESOURCE_HRC_
44 #include "core_resource.hrc"
45 #endif
46 
47 #ifndef _TOOLS_DEBUG_HXX
48 #include <tools/debug.hxx>
49 #endif
50 #ifndef _COMPHELPER_SEQUENCE_HXX_
51 #include <comphelper/sequence.hxx>
52 #endif
53 #ifndef _COMPHELPER_ENUMHELPER_HXX_
54 #include <comphelper/enumhelper.hxx>
55 #endif
56 #ifndef _COMPHELPER_EXTRACT_HXX_
57 #include <comphelper/extract.hxx>
58 #endif
59 #ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
60 #include <com/sun/star/lang/XComponent.hpp>
61 #endif
62 #ifndef _COMPHELPER_TYPES_HXX_
63 #include <comphelper/types.hxx>
64 #endif
65 
66 using namespace ::com::sun::star::uno;
67 using namespace ::com::sun::star::lang;
68 using namespace ::com::sun::star::beans;
69 using namespace ::com::sun::star::container;
70 using namespace ::osl;
71 using namespace ::comphelper;
72 using namespace ::cppu;
73 
74 //........................................................................
75 namespace dbaccess
76 {
77 //........................................................................
78 
79 //==========================================================================
80 //= OBookmarkContainer
81 //==========================================================================
82 DBG_NAME(OBookmarkContainer)
83 //--------------------------------------------------------------------------
84 OBookmarkContainer::OBookmarkContainer(OWeakObject& _rParent, Mutex& _rMutex)
85 	:m_rParent(_rParent)
86 	,m_aContainerListeners(_rMutex)
87 	,m_rMutex(_rMutex)
88 {
89 	DBG_CTOR(OBookmarkContainer, NULL);
90 }
91 
92 //--------------------------------------------------------------------------
93 void OBookmarkContainer::dispose()
94 {
95 	MutexGuard aGuard(m_rMutex);
96 
97 	// say our listeners goobye
98 	EventObject aEvt(*this);
99 	m_aContainerListeners.disposeAndClear(aEvt);
100 
101 	// remove our elements
102 	m_aBookmarksIndexed.clear();
103 	m_aBookmarks.clear();
104 }
105 
106 //--------------------------------------------------------------------------
107 void SAL_CALL OBookmarkContainer::acquire(  ) throw()
108 {
109 	m_rParent.acquire();
110 }
111 
112 //--------------------------------------------------------------------------
113 void SAL_CALL OBookmarkContainer::release(  ) throw()
114 {
115 	m_rParent.release();
116 }
117 
118 //--------------------------------------------------------------------------
119 OBookmarkContainer::~OBookmarkContainer()
120 {
121 	DBG_DTOR(OBookmarkContainer, NULL);
122 }
123 
124 // XServiceInfo
125 //--------------------------------------------------------------------------
126 ::rtl::OUString SAL_CALL OBookmarkContainer::getImplementationName(  ) throw(RuntimeException)
127 {
128 	return ::rtl::OUString::createFromAscii("com.sun.star.comp.dba.OBookmarkContainer");
129 }
130 
131 //--------------------------------------------------------------------------
132 sal_Bool SAL_CALL OBookmarkContainer::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
133 {
134 	MutexGuard aGuard(m_rMutex);
135 	checkValid(sal_False);
136 	return findValue(getSupportedServiceNames(), _rServiceName, sal_True).getLength() != 0;
137 }
138 
139 //--------------------------------------------------------------------------
140 Sequence< ::rtl::OUString > SAL_CALL OBookmarkContainer::getSupportedServiceNames(  ) throw(RuntimeException)
141 {
142 	Sequence< ::rtl::OUString > aReturn(1);
143 	aReturn.getArray()[0] = ::rtl::OUString::createFromAscii("com.sun.star.sdb.DefinitionContainer");
144 	return aReturn;
145 }
146 
147 // XNameContainer
148 //--------------------------------------------------------------------------
149 void SAL_CALL OBookmarkContainer::insertByName( const ::rtl::OUString& _rName, const Any& aElement ) throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
150 {
151 	MutexGuard aGuard(m_rMutex);
152 	checkValid(sal_True);
153 
154 	if (checkExistence(_rName))
155 		throw ElementExistException();
156 
157 	if (0 == _rName.getLength())
158 		throw IllegalArgumentException();
159 
160 	// approve the new object
161 	::rtl::OUString sNewLink;
162 	if (!(aElement >>= sNewLink))
163 		throw IllegalArgumentException();
164 
165 
166 	implAppend(_rName, sNewLink);
167 
168 	// notify the listeners
169 	if (m_aContainerListeners.getLength())
170 	{
171 		ContainerEvent aEvent(*this, makeAny(_rName), makeAny(sNewLink), Any());
172 		OInterfaceIteratorHelper aListenerIterator(m_aContainerListeners);
173 		while (aListenerIterator.hasMoreElements())
174 			static_cast< XContainerListener* >(aListenerIterator.next())->elementInserted(aEvent);
175 	}
176 }
177 
178 //--------------------------------------------------------------------------
179 void SAL_CALL OBookmarkContainer::removeByName( const ::rtl::OUString& _rName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
180 {
181 	::rtl::OUString sOldBookmark;
182 	{
183 		MutexGuard aGuard(m_rMutex);
184 		checkValid(sal_True);
185 
186 		// check the arguments
187 		if (!_rName.getLength())
188 			throw IllegalArgumentException();
189 
190 		if (!checkExistence(_rName))
191 			throw NoSuchElementException();
192 
193 		// the old element (for the notifications)
194 		sOldBookmark = m_aBookmarks[_rName];
195 
196 		// do the removal
197 		implRemove(_rName);
198 	}
199 
200 	// notify the listeners
201 	if (m_aContainerListeners.getLength())
202 	{
203 		ContainerEvent aEvent(*this, makeAny(_rName), makeAny(sOldBookmark), Any());
204 		OInterfaceIteratorHelper aListenerIterator(m_aContainerListeners);
205 		while (aListenerIterator.hasMoreElements())
206 			static_cast< XContainerListener* >(aListenerIterator.next())->elementRemoved(aEvent);
207 	}
208 }
209 
210 // XNameReplace
211 //--------------------------------------------------------------------------
212 void SAL_CALL OBookmarkContainer::replaceByName( const ::rtl::OUString& _rName, const Any& aElement ) throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
213 {
214 	ClearableMutexGuard aGuard(m_rMutex);
215 	checkValid(sal_True);
216 
217 	// check the arguments
218 	if (!_rName.getLength())
219 		throw IllegalArgumentException();
220 
221 	// do we have such an element?
222 	if (!checkExistence(_rName))
223 		throw NoSuchElementException();
224 
225 	// approve the new object
226 	::rtl::OUString sNewLink;
227 	if (!(aElement >>= sNewLink))
228 		throw IllegalArgumentException();
229 
230 	// the old element (for the notifications)
231 	::rtl::OUString sOldLink = m_aBookmarks[_rName];
232 
233 	// do the replace
234 	implReplace(_rName, sNewLink);
235 
236 	// notify the listeners
237 	aGuard.clear();
238 	if (m_aContainerListeners.getLength())
239 	{
240 		ContainerEvent aEvent(*this, makeAny(_rName), makeAny(sNewLink), makeAny(sOldLink));
241 		OInterfaceIteratorHelper aListenerIterator(m_aContainerListeners);
242 		while (aListenerIterator.hasMoreElements())
243 			static_cast< XContainerListener* >(aListenerIterator.next())->elementReplaced(aEvent);
244 	}
245 }
246 
247 //--------------------------------------------------------------------------
248 void SAL_CALL OBookmarkContainer::addContainerListener( const Reference< XContainerListener >& _rxListener ) throw(RuntimeException)
249 {
250 	MutexGuard aGuard(m_rMutex);
251 	if (_rxListener.is())
252 		m_aContainerListeners.addInterface(_rxListener);
253 }
254 
255 //--------------------------------------------------------------------------
256 void SAL_CALL OBookmarkContainer::removeContainerListener( const Reference< XContainerListener >& _rxListener ) throw(RuntimeException)
257 {
258 	MutexGuard aGuard(m_rMutex);
259 	if (_rxListener.is())
260 		m_aContainerListeners.removeInterface(_rxListener);
261 }
262 
263 // XElementAccess
264 //--------------------------------------------------------------------------
265 Type SAL_CALL OBookmarkContainer::getElementType( ) throw (RuntimeException)
266 {
267 	MutexGuard aGuard(m_rMutex);
268 	checkValid(sal_False);
269 	return ::getCppuType( static_cast< ::rtl::OUString* >(NULL) );
270 }
271 
272 //--------------------------------------------------------------------------
273 sal_Bool SAL_CALL OBookmarkContainer::hasElements( ) throw (RuntimeException)
274 {
275 	MutexGuard aGuard(m_rMutex);
276 	checkValid(sal_False);
277 	return !m_aBookmarks.empty();
278 }
279 
280 // XEnumerationAccess
281 //--------------------------------------------------------------------------
282 Reference< XEnumeration > SAL_CALL OBookmarkContainer::createEnumeration(  ) throw(RuntimeException)
283 {
284 	MutexGuard aGuard(m_rMutex);
285 	checkValid(sal_False);
286 	return new ::comphelper::OEnumerationByIndex(static_cast<XIndexAccess*>(this));
287 }
288 
289 //--------------------------------------------------------------------------
290 // XIndexAccess
291 sal_Int32 SAL_CALL OBookmarkContainer::getCount(  ) throw(RuntimeException)
292 {
293 	MutexGuard aGuard(m_rMutex);
294 	checkValid(sal_False);
295 	return m_aBookmarks.size();
296 }
297 
298 //--------------------------------------------------------------------------
299 Any SAL_CALL OBookmarkContainer::getByIndex( sal_Int32 _nIndex ) throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
300 {
301 	MutexGuard aGuard(m_rMutex);
302 	checkValid(sal_False);
303 
304 	if ((_nIndex < 0) || (_nIndex >= (sal_Int32)m_aBookmarksIndexed.size()))
305 		throw IndexOutOfBoundsException();
306 
307 	return makeAny(m_aBookmarksIndexed[_nIndex]->second);
308 }
309 
310 //--------------------------------------------------------------------------
311 Any SAL_CALL OBookmarkContainer::getByName( const ::rtl::OUString& _rName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
312 {
313 	MutexGuard aGuard(m_rMutex);
314 	checkValid(sal_False);
315 
316 	if (!checkExistence(_rName))
317 		throw NoSuchElementException();
318 
319 	return makeAny(m_aBookmarks[_rName]);
320 }
321 
322 //--------------------------------------------------------------------------
323 Sequence< ::rtl::OUString > SAL_CALL OBookmarkContainer::getElementNames(  ) throw(RuntimeException)
324 {
325 	MutexGuard aGuard(m_rMutex);
326 	checkValid(sal_False);
327 
328 	Sequence< ::rtl::OUString > aNames(m_aBookmarks.size());
329 	::rtl::OUString* pNames = aNames.getArray();
330 	;
331 	for	(	ConstMapIteratorVectorIterator aNameIter = m_aBookmarksIndexed.begin();
332 			aNameIter != m_aBookmarksIndexed.end();
333 			++pNames, ++aNameIter
334 		)
335 	{
336 		*pNames = (*aNameIter)->first;
337 	}
338 
339 	return aNames;
340 }
341 
342 //--------------------------------------------------------------------------
343 sal_Bool SAL_CALL OBookmarkContainer::hasByName( const ::rtl::OUString& _rName ) throw(RuntimeException)
344 {
345 	MutexGuard aGuard(m_rMutex);
346 	checkValid(sal_False);
347 
348 	return checkExistence(_rName);
349 }
350 
351 //--------------------------------------------------------------------------
352 void OBookmarkContainer::implRemove(const ::rtl::OUString& _rName)
353 {
354 	MutexGuard aGuard(m_rMutex);
355 
356 	// look for the name in the index access vector
357 	MapString2StringIterator aMapPos = m_aBookmarks.end();
358 	for (	MapIteratorVectorIterator aSearch = m_aBookmarksIndexed.begin();
359 			aSearch != m_aBookmarksIndexed.end();
360 			++aSearch
361 		)
362 	{
363 #ifdef DBG_UTIL
364 		::rtl::OUString sName = (*aSearch)->first;
365 #endif
366 		if ((*aSearch)->first == _rName)
367 		{
368 			aMapPos = *aSearch;
369 			m_aBookmarksIndexed.erase(aSearch);
370 			break;
371 		}
372 	}
373 
374 	if (m_aBookmarks.end() == aMapPos)
375 	{
376 		DBG_ERROR("OBookmarkContainer::implRemove: inconsistence!");
377 		return;
378 	}
379 
380 	// remove the map entries
381 	m_aBookmarks.erase(aMapPos);
382 }
383 
384 //--------------------------------------------------------------------------
385 void OBookmarkContainer::implAppend(const ::rtl::OUString& _rName, const ::rtl::OUString& _rDocumentLocation)
386 {
387 	MutexGuard aGuard(m_rMutex);
388 
389 	OSL_ENSURE(m_aBookmarks.find(_rName) == m_aBookmarks.end(),"Bookmark already known!");
390 	m_aBookmarksIndexed.push_back(m_aBookmarks.insert(	MapString2String::value_type(_rName,_rDocumentLocation)).first);
391 }
392 
393 //--------------------------------------------------------------------------
394 void OBookmarkContainer::implReplace(const ::rtl::OUString& _rName, const ::rtl::OUString& _rNewLink)
395 {
396 	MutexGuard aGuard(m_rMutex);
397 	DBG_ASSERT(checkExistence(_rName), "OBookmarkContainer::implReplace : invalid name !");
398 
399 	m_aBookmarks[_rName] = _rNewLink;
400 }
401 
402 //--------------------------------------------------------------------------
403 void OBookmarkContainer::checkValid(sal_Bool /*_bIntendWriteAccess*/) const throw (RuntimeException, DisposedException)
404 {
405 }
406 
407 //--------------------------------------------------------------------------
408 Reference< XInterface > SAL_CALL OBookmarkContainer::getParent(  ) throw (RuntimeException)
409 {
410 	return m_rParent;
411 }
412 
413 //--------------------------------------------------------------------------
414 void SAL_CALL OBookmarkContainer::setParent( const Reference< XInterface >& /*Parent*/ ) throw (NoSupportException, RuntimeException)
415 {
416 	throw NoSupportException();
417 }
418 
419 //........................................................................
420 }	// namespace dbaccess
421 //........................................................................
422