1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26 
27 #include <set>
28 
29 #include "svx/UnoNamespaceMap.hxx"
30 #include <com/sun/star/container/XNameAccess.hpp>
31 #include <com/sun/star/lang/XServiceInfo.hpp>
32 
33 #ifndef _CPPUHELPER_IMPLBASE3_HXX_
34 #include <cppuhelper/implbase2.hxx>
35 #endif
36 #include <osl/diagnose.h>
37 #include <osl/mutex.hxx>
38 #include <comphelper/stl_types.hxx>
39 #include <svl/itempool.hxx>
40 #include "svx/unoapi.hxx"
41 #include "editeng/xmlcnitm.hxx"
42 
43 
44 using namespace ::comphelper;
45 using namespace ::osl;
46 using namespace ::cppu;
47 using namespace ::com::sun::star;
48 using namespace ::com::sun::star::uno;
49 using namespace ::com::sun::star::container;
50 using namespace ::com::sun::star::drawing;
51 using namespace ::com::sun::star::lang;
52 using namespace ::com::sun::star::beans;
53 
54 namespace svx
55 {
56 	/**	implements a component to export namespaces of all SvXMLAttrContainerItem inside
57 		one or two pools with a variable count of which ids.
58 	*/
59 	class NamespaceMap : public WeakImplHelper2< XNameAccess, XServiceInfo >
60 	{
61 	private:
62 		sal_uInt16* mpWhichIds;
63 		SfxItemPool* mpPool;
64 
65 	public:
66 		NamespaceMap( sal_uInt16* pWhichIds, SfxItemPool* pPool );
67 		virtual ~NamespaceMap();
68 
69 		// XNameAccess
70 		virtual Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw (NoSuchElementException, WrappedTargetException, RuntimeException);
71 		virtual Sequence< ::rtl::OUString > SAL_CALL getElementNames(  ) throw (RuntimeException);
72 		virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (RuntimeException);
73 
74 		// XElementAccess
75 		virtual Type SAL_CALL getElementType(  ) throw (RuntimeException);
76 		virtual sal_Bool SAL_CALL hasElements(  ) throw (RuntimeException);
77 
78 		// XServiceInfo
79 		virtual ::rtl::OUString SAL_CALL getImplementationName(  ) throw(RuntimeException);
80 		virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(RuntimeException);
81 		virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  ) throw(RuntimeException);
82 	};
83 
NamespaceMap_createInstance(sal_uInt16 * pWhichIds,SfxItemPool * pPool1,SfxItemPool *)84 	Reference< XInterface > SAL_CALL NamespaceMap_createInstance( sal_uInt16* pWhichIds, SfxItemPool* pPool1, SfxItemPool* )
85 	{
86 		return (XWeak*)new NamespaceMap( pWhichIds, pPool1 );
87 	}
88 
NamespaceMap_createInstance(sal_uInt16 * pWhichIds,SfxItemPool * pPool)89 	Reference< XInterface > SAL_CALL NamespaceMap_createInstance( sal_uInt16* pWhichIds, SfxItemPool* pPool )
90 	{
91 		return (XWeak*)new NamespaceMap( pWhichIds, pPool );
92 	}
93 
NamespaceMap_getSupportedServiceNames()94 	Sequence< ::rtl::OUString > SAL_CALL NamespaceMap_getSupportedServiceNames()
95 		throw()
96 	{
97 		Sequence< ::rtl::OUString > aSupportedServiceNames( 1 );
98 		aSupportedServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.NamespaceMap" ) );
99 		return aSupportedServiceNames;
100 	}
101 
NamespaceMap_getImplementationName()102 	::rtl::OUString SAL_CALL NamespaceMap_getImplementationName()
103 		throw()
104 	{
105 		return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Svx.NamespaceMap" ) );
106 	}
107 
108 
109 
110 	class NamespaceIteratorImpl
111 	{
112 	private:
113 		SfxItemPool* mpPool;
114 
115 		sal_uInt16* mpWhichId;
116 
117 		sal_uInt32 mnItemCount;
118 		sal_uInt32 mnItem;
119 
120 		const SvXMLAttrContainerItem* mpCurrentAttr;
121 		sal_uInt16 mnCurrentAttr;
122 
123 	public:
124 
125 		NamespaceIteratorImpl( sal_uInt16* pWhichIds, SfxItemPool* pPool );
126 
127 		sal_Bool next( ::rtl::OUString& rPrefix, ::rtl::OUString& rURL );
128 	};
129 }
130 
131 using namespace ::svx;
132 
133 // -------------
134 
NamespaceIteratorImpl(sal_uInt16 * pWhichIds,SfxItemPool * pPool)135 NamespaceIteratorImpl::NamespaceIteratorImpl( sal_uInt16* pWhichIds, SfxItemPool* pPool )
136 {
137 	mpPool = pPool;
138 	mpCurrentAttr = NULL;
139 	mnCurrentAttr = 0;
140 
141 	mpWhichId = pWhichIds;
142 
143 	mnItem = 0;
144 	mnItemCount = (mpWhichId && (0 != *mpWhichId) && mpPool) ? mpPool->GetItemCount2( *mpWhichId ) : 0;
145 }
146 
next(::rtl::OUString & rPrefix,::rtl::OUString & rURL)147 sal_Bool NamespaceIteratorImpl::next( ::rtl::OUString& rPrefix, ::rtl::OUString& rURL )
148 {
149 	// we still need to process the current attribute
150 	if( mpCurrentAttr && (mnCurrentAttr != USHRT_MAX) )
151 	{
152 		rPrefix = mpCurrentAttr->GetPrefix( mnCurrentAttr );
153 		rURL = mpCurrentAttr->GetNamespace( mnCurrentAttr );
154 
155 		mnCurrentAttr = mpCurrentAttr->GetNextNamespaceIndex( mnCurrentAttr );
156 		return sal_True;
157 	}
158 
159 	// we need the next namespace item
160 	mpCurrentAttr = NULL;
161 
162 	const SfxPoolItem* pItem = 0;
163 	// look for the next available item in the current pool
164 	while( (mnItem < mnItemCount) && ( NULL == (pItem = mpPool->GetItem2( *mpWhichId, mnItem ) ) ) )
165 		mnItem++;
166 
167 	// are we finished with the current whichid?
168 	if( mnItem == mnItemCount )
169 	{
170 		mpWhichId++;
171 
172 		// are we finished with the current pool?
173 		if( 0 != *mpWhichId )
174 		{
175 			mnItem = 0;
176 			mnItemCount = (mpWhichId && (0 != *mpWhichId) && mpPool) ? mpPool->GetItemCount2( *mpWhichId ) : 0;
177 			return next( rPrefix, rURL );
178 		}
179 
180 		pItem = NULL;
181 	}
182 
183 	if( pItem )
184 	{
185 		mnItem++;
186 
187 		// get that item and see if there namespaces inside
188 		const SvXMLAttrContainerItem *pUnknown = (const SvXMLAttrContainerItem *)pItem;
189 		if( (pUnknown->GetAttrCount() > 0) )
190 		{
191 			mpCurrentAttr = pUnknown;
192 			mnCurrentAttr = pUnknown->GetFirstNamespaceIndex();
193 		}
194 		return next( rPrefix, rURL );
195 	}
196 
197 	return false;
198 }
199 
200 // -------------
201 
NamespaceMap(sal_uInt16 * pWhichIds,SfxItemPool * pPool)202 NamespaceMap::NamespaceMap( sal_uInt16* pWhichIds, SfxItemPool* pPool )
203 : mpWhichIds( pWhichIds ), mpPool( pPool )
204 {
205 }
206 
~NamespaceMap()207 NamespaceMap::~NamespaceMap()
208 {
209 }
210 
211 // XNameAccess
getByName(const::rtl::OUString & aName)212 Any SAL_CALL NamespaceMap::getByName( const ::rtl::OUString& aName ) throw (NoSuchElementException, WrappedTargetException, RuntimeException)
213 {
214 	NamespaceIteratorImpl aIter( mpWhichIds, mpPool );
215 
216 	::rtl::OUString aPrefix;
217 	::rtl::OUString aURL;
218 
219 	sal_Bool bFound;
220 
221 	do
222 	{
223 		bFound = aIter.next( aPrefix, aURL );
224 	}
225 	while( bFound && (aPrefix != aName ) );
226 
227 	if( !bFound )
228 		throw NoSuchElementException();
229 
230 	return makeAny( aURL );
231 }
232 
getElementNames()233 Sequence< ::rtl::OUString > SAL_CALL NamespaceMap::getElementNames() throw (RuntimeException)
234 {
235 	NamespaceIteratorImpl aIter( mpWhichIds, mpPool );
236 
237 	::rtl::OUString aPrefix;
238 	::rtl::OUString aURL;
239 
240 	std::set< ::rtl::OUString, comphelper::UStringLess > aPrefixSet;
241 
242 	while( aIter.next( aPrefix, aURL ) )
243 		aPrefixSet.insert( aPrefix );
244 
245 	Sequence< ::rtl::OUString > aSeq( aPrefixSet.size() );
246 	::rtl::OUString* pPrefixes = aSeq.getArray();
247 
248 	std::set< ::rtl::OUString, comphelper::UStringLess >::iterator aPrefixIter( aPrefixSet.begin() );
249 	const std::set< ::rtl::OUString, comphelper::UStringLess >::iterator aEnd( aPrefixSet.end() );
250 
251 	while( aPrefixIter != aEnd )
252 	{
253 		*pPrefixes++ = *aPrefixIter++;
254 	}
255 
256 	return aSeq;
257 }
258 
hasByName(const::rtl::OUString & aName)259 sal_Bool SAL_CALL NamespaceMap::hasByName( const ::rtl::OUString& aName ) throw (RuntimeException)
260 {
261 	NamespaceIteratorImpl aIter( mpWhichIds, mpPool );
262 
263 	::rtl::OUString aPrefix;
264 	::rtl::OUString aURL;
265 
266 	sal_Bool bFound;
267 
268 	do
269 	{
270 		bFound = aIter.next( aPrefix, aURL );
271 	}
272 	while( bFound && (aPrefix != aName ) );
273 
274 	return bFound;
275 }
276 
277 // XElementAccess
getElementType()278 Type SAL_CALL NamespaceMap::getElementType() throw (RuntimeException)
279 {
280 	return ::getCppuType( (const ::rtl::OUString*) 0 );
281 }
282 
hasElements()283 sal_Bool SAL_CALL NamespaceMap::hasElements() throw (RuntimeException)
284 {
285 	NamespaceIteratorImpl aIter( mpWhichIds, mpPool );
286 
287 	::rtl::OUString aPrefix;
288 	::rtl::OUString aURL;
289 
290 	return aIter.next( aPrefix, aURL );
291 }
292 
293 // XServiceInfo
getImplementationName()294 ::rtl::OUString SAL_CALL NamespaceMap::getImplementationName(  )
295 	throw(RuntimeException)
296 {
297 	return NamespaceMap_getImplementationName();
298 }
299 
supportsService(const::rtl::OUString &)300 sal_Bool SAL_CALL NamespaceMap::supportsService( const ::rtl::OUString& )
301 	throw(RuntimeException)
302 {
303 	return sal_True;
304 }
305 
getSupportedServiceNames()306 Sequence< ::rtl::OUString > SAL_CALL NamespaceMap::getSupportedServiceNames(  )
307 	throw(RuntimeException)
308 {
309 	return NamespaceMap_getSupportedServiceNames();
310 }
311