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