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 #ifndef _CPPUHELPER_INTERFACECONTAINER_HXX_
28 #define _CPPUHELPER_INTERFACECONTAINER_HXX_
29 
30 #include <cppuhelper/interfacecontainer.h>
31 
32 
33 namespace cppu
34 {
35 
36 template< class key , class hashImpl , class equalImpl >
37 inline OMultiTypeInterfaceContainerHelperVar< key , hashImpl , equalImpl >::OMultiTypeInterfaceContainerHelperVar( ::osl::Mutex & rMutex_ )
38 	SAL_THROW( () )
39 	: rMutex( rMutex_ )
40 {
41 	m_pMap = new InterfaceMap;
42 }
43 
44 //===================================================================
45 template< class key , class hashImpl , class equalImpl >
46 inline OMultiTypeInterfaceContainerHelperVar< key , hashImpl , equalImpl >::~OMultiTypeInterfaceContainerHelperVar()
47 	SAL_THROW( () )
48 {
49 	typename InterfaceMap::iterator iter = m_pMap->begin();
50 	typename InterfaceMap::iterator end = m_pMap->end();
51 
52 	while( iter != end )
53 	{
54 		delete (OInterfaceContainerHelper*)(*iter).second;
55 		(*iter).second = 0;
56 		++iter;
57 	}
58 	delete m_pMap;
59 }
60 
61 //===================================================================
62 template< class key , class hashImpl , class equalImpl >
63 inline ::com::sun::star::uno::Sequence< key > OMultiTypeInterfaceContainerHelperVar< key , hashImpl , equalImpl >::getContainedTypes() const
64 	SAL_THROW( () )
65 {
66 	::osl::MutexGuard aGuard( rMutex );
67 	typename InterfaceMap::size_type nSize = m_pMap->size();
68 	if( nSize != 0 )
69 	{
70 		::com::sun::star::uno::Sequence< key > aInterfaceTypes( nSize );
71 		key * pArray = aInterfaceTypes.getArray();
72 
73 		typename InterfaceMap::iterator iter = m_pMap->begin();
74 		typename InterfaceMap::iterator end = m_pMap->end();
75 
76 		sal_uInt32 i = 0;
77 		while( iter != end )
78 		{
79 			// are interfaces added to this container?
80 			if( ((OInterfaceContainerHelper*)(*iter).second)->getLength() )
81 				// yes, put the type in the array
82 				pArray[i++] = (*iter).first;
83 			iter++;
84 		}
85 		if( i != nSize ) {
86 			// may be empty container, reduce the sequence to the right size
87 			aInterfaceTypes = ::com::sun::star::uno::Sequence<key>( pArray, i );
88 		}
89 		return aInterfaceTypes;
90 	}
91 	return ::com::sun::star::uno::Sequence<key>();
92 }
93 
94 //===================================================================
95 template< class key , class hashImpl , class equalImpl >
96 OInterfaceContainerHelper * OMultiTypeInterfaceContainerHelperVar< key , hashImpl , equalImpl >::getContainer(
97 	const key & rKey ) const SAL_THROW( () )
98 {
99 	::osl::MutexGuard aGuard( rMutex );
100 
101  	typename InterfaceMap::iterator iter = find( rKey );
102 	if( iter != m_pMap->end() )
103 			return (OInterfaceContainerHelper*) (*iter).second;
104 	return 0;
105 }
106 
107 //===================================================================
108 template< class key , class hashImpl , class equalImpl >
109 sal_Int32 OMultiTypeInterfaceContainerHelperVar< key , hashImpl , equalImpl >::addInterface(
110 	const key & rKey,
111 	const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & rListener )
112 	SAL_THROW( () )
113 {
114 	::osl::MutexGuard aGuard( rMutex );
115 	typename InterfaceMap::iterator iter = find( rKey );
116 	if( iter == m_pMap->end() )
117 	{
118 		OInterfaceContainerHelper * pLC = new OInterfaceContainerHelper( rMutex );
119         m_pMap->push_back(std::pair<key, void*>(rKey, pLC));
120 		return pLC->addInterface( rListener );
121 	}
122 	else
123 		return ((OInterfaceContainerHelper*)(*iter).second)->addInterface( rListener );
124 }
125 
126 //===================================================================
127 template< class key , class hashImpl , class equalImpl >
128 inline sal_Int32 OMultiTypeInterfaceContainerHelperVar< key , hashImpl , equalImpl >::removeInterface(
129 	const key & rKey,
130 	const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & rListener )
131 	SAL_THROW( () )
132 {
133 	::osl::MutexGuard aGuard( rMutex );
134 
135 	// search container with id nUik
136 	typename InterfaceMap::iterator iter = find( rKey );
137     // container found?
138 	if( iter != m_pMap->end() )
139         return ((OInterfaceContainerHelper*)(*iter).second)->removeInterface( rListener );
140 
141 	// no container with this id. Always return 0
142 	return 0;
143 }
144 
145 //===================================================================
146 template< class key , class hashImpl , class equalImpl >
147 void OMultiTypeInterfaceContainerHelperVar< key , hashImpl , equalImpl >::disposeAndClear(
148 	const ::com::sun::star::lang::EventObject & rEvt )
149 	SAL_THROW( () )
150 {
151 	typename InterfaceMap::size_type nSize = 0;
152 	OInterfaceContainerHelper ** ppListenerContainers = NULL;
153 	{
154 		::osl::MutexGuard aGuard( rMutex );
155         nSize = m_pMap->size();
156 		if( nSize )
157 		{
158 			typedef OInterfaceContainerHelper* ppp;
159 			ppListenerContainers = new ppp[nSize];
160 			//ppListenerContainers = new (ListenerContainer*)[nSize];
161 
162 			typename InterfaceMap::iterator iter = m_pMap->begin();
163 			typename InterfaceMap::iterator end = m_pMap->end();
164 
165 			typename InterfaceMap::size_type i = 0;
166 			while( iter != end )
167 			{
168 				ppListenerContainers[i++] = (OInterfaceContainerHelper*)(*iter).second;
169 				++iter;
170 			}
171 		}
172 	}
173 
174 	// create a copy, because do not fire event in a guarded section
175 	for( typename InterfaceMap::size_type i = 0; i < nSize; i++ )
176 	{
177 		if( ppListenerContainers[i] )
178 			ppListenerContainers[i]->disposeAndClear( rEvt );
179 	}
180 
181 	delete [] ppListenerContainers;
182 }
183 
184 //===================================================================
185 template< class key , class hashImpl , class equalImpl >
186 void OMultiTypeInterfaceContainerHelperVar< key , hashImpl , equalImpl >::clear() SAL_THROW( () )
187 {
188 	::osl::MutexGuard aGuard( rMutex );
189 	typename InterfaceMap::iterator iter = m_pMap->begin();
190 	typename InterfaceMap::iterator end = m_pMap->end();
191 
192 	while( iter != end )
193 	{
194 		((OInterfaceContainerHelper*)(*iter).second)->clear();
195 		++iter;
196 	}
197 }
198 
199 
200 }
201 
202 #endif
203 
204