xref: /trunk/main/svx/source/unodraw/UnoNamespaceMap.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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_svx.hxx"
30 
31 #include <set>
32 
33 #include "svx/UnoNamespaceMap.hxx"
34 #include <com/sun/star/container/XNameAccess.hpp>
35 #include <com/sun/star/lang/XServiceInfo.hpp>
36 
37 #ifndef _CPPUHELPER_IMPLBASE3_HXX_
38 #include <cppuhelper/implbase2.hxx>
39 #endif
40 #include <osl/diagnose.h>
41 #include <osl/mutex.hxx>
42 #include <comphelper/stl_types.hxx>
43 #include <svl/itempool.hxx>
44 #include "svx/unoapi.hxx"
45 #include "editeng/xmlcnitm.hxx"
46 
47 
48 using namespace ::comphelper;
49 using namespace ::osl;
50 using namespace ::cppu;
51 using namespace ::com::sun::star;
52 using namespace ::com::sun::star::uno;
53 using namespace ::com::sun::star::container;
54 using namespace ::com::sun::star::drawing;
55 using namespace ::com::sun::star::lang;
56 using namespace ::com::sun::star::beans;
57 
58 namespace svx
59 {
60     /** implements a component to export namespaces of all SvXMLAttrContainerItem inside
61         one or two pools with a variable count of which ids.
62     */
63     class NamespaceMap : public WeakImplHelper2< XNameAccess, XServiceInfo >
64     {
65     private:
66         sal_uInt16* mpWhichIds;
67         SfxItemPool* mpPool;
68 
69     public:
70         NamespaceMap( sal_uInt16* pWhichIds, SfxItemPool* pPool );
71         virtual ~NamespaceMap();
72 
73         // XNameAccess
74         virtual Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw (NoSuchElementException, WrappedTargetException, RuntimeException);
75         virtual Sequence< ::rtl::OUString > SAL_CALL getElementNames(  ) throw (RuntimeException);
76         virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (RuntimeException);
77 
78         // XElementAccess
79         virtual Type SAL_CALL getElementType(  ) throw (RuntimeException);
80         virtual sal_Bool SAL_CALL hasElements(  ) throw (RuntimeException);
81 
82         // XServiceInfo
83         virtual ::rtl::OUString SAL_CALL getImplementationName(  ) throw(RuntimeException);
84         virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(RuntimeException);
85         virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  ) throw(RuntimeException);
86     };
87 
88     Reference< XInterface > SAL_CALL NamespaceMap_createInstance( sal_uInt16* pWhichIds, SfxItemPool* pPool1, SfxItemPool* )
89     {
90         return (XWeak*)new NamespaceMap( pWhichIds, pPool1 );
91     }
92 
93     Reference< XInterface > SAL_CALL NamespaceMap_createInstance( sal_uInt16* pWhichIds, SfxItemPool* pPool )
94     {
95         return (XWeak*)new NamespaceMap( pWhichIds, pPool );
96     }
97 
98     Sequence< ::rtl::OUString > SAL_CALL NamespaceMap_getSupportedServiceNames()
99         throw()
100     {
101         Sequence< ::rtl::OUString > aSupportedServiceNames( 1 );
102         aSupportedServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.NamespaceMap" ) );
103         return aSupportedServiceNames;
104     }
105 
106     ::rtl::OUString SAL_CALL NamespaceMap_getImplementationName()
107         throw()
108     {
109         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Svx.NamespaceMap" ) );
110     }
111 
112 
113 
114     class NamespaceIteratorImpl
115     {
116     private:
117         SfxItemPool* mpPool;
118 
119         sal_uInt16* mpWhichId;
120 
121         sal_uInt32 mnItemCount;
122         sal_uInt32 mnItem;
123 
124         const SvXMLAttrContainerItem* mpCurrentAttr;
125         sal_uInt16 mnCurrentAttr;
126 
127     public:
128 
129         NamespaceIteratorImpl( sal_uInt16* pWhichIds, SfxItemPool* pPool );
130 
131         sal_Bool next( ::rtl::OUString& rPrefix, ::rtl::OUString& rURL );
132     };
133 }
134 
135 using namespace ::svx;
136 
137 // -------------
138 
139 NamespaceIteratorImpl::NamespaceIteratorImpl( sal_uInt16* pWhichIds, SfxItemPool* pPool )
140 {
141     mpPool = pPool;
142     mpCurrentAttr = NULL;
143     mnCurrentAttr = 0;
144 
145     mpWhichId = pWhichIds;
146 
147     mnItem = 0;
148     mnItemCount = (mpWhichId && (0 != *mpWhichId) && mpPool) ? mpPool->GetItemCount2( *mpWhichId ) : 0;
149 }
150 
151 sal_Bool NamespaceIteratorImpl::next( ::rtl::OUString& rPrefix, ::rtl::OUString& rURL )
152 {
153     // we still need to process the current attribute
154     if( mpCurrentAttr && (mnCurrentAttr != USHRT_MAX) )
155     {
156         rPrefix = mpCurrentAttr->GetPrefix( mnCurrentAttr );
157         rURL = mpCurrentAttr->GetNamespace( mnCurrentAttr );
158 
159         mnCurrentAttr = mpCurrentAttr->GetNextNamespaceIndex( mnCurrentAttr );
160         return sal_True;
161     }
162 
163     // we need the next namespace item
164     mpCurrentAttr = NULL;
165 
166     const SfxPoolItem* pItem = 0;
167     // look for the next available item in the current pool
168     while( (mnItem < mnItemCount) && ( NULL == (pItem = mpPool->GetItem2( *mpWhichId, mnItem ) ) ) )
169         mnItem++;
170 
171     // are we finished with the current whichid?
172     if( mnItem == mnItemCount )
173     {
174         mpWhichId++;
175 
176         // are we finished with the current pool?
177         if( 0 != *mpWhichId )
178         {
179             mnItem = 0;
180             mnItemCount = (mpWhichId && (0 != *mpWhichId) && mpPool) ? mpPool->GetItemCount2( *mpWhichId ) : 0;
181             return next( rPrefix, rURL );
182         }
183 
184         pItem = NULL;
185     }
186 
187     if( pItem )
188     {
189         mnItem++;
190 
191         // get that item and see if there namespaces inside
192         const SvXMLAttrContainerItem *pUnknown = (const SvXMLAttrContainerItem *)pItem;
193         if( (pUnknown->GetAttrCount() > 0) )
194         {
195             mpCurrentAttr = pUnknown;
196             mnCurrentAttr = pUnknown->GetFirstNamespaceIndex();
197         }
198         return next( rPrefix, rURL );
199     }
200 
201     return false;
202 }
203 
204 // -------------
205 
206 NamespaceMap::NamespaceMap( sal_uInt16* pWhichIds, SfxItemPool* pPool )
207 : mpWhichIds( pWhichIds ), mpPool( pPool )
208 {
209 }
210 
211 NamespaceMap::~NamespaceMap()
212 {
213 }
214 
215 // XNameAccess
216 Any SAL_CALL NamespaceMap::getByName( const ::rtl::OUString& aName ) throw (NoSuchElementException, WrappedTargetException, RuntimeException)
217 {
218     NamespaceIteratorImpl aIter( mpWhichIds, mpPool );
219 
220     ::rtl::OUString aPrefix;
221     ::rtl::OUString aURL;
222 
223     sal_Bool bFound;
224 
225     do
226     {
227         bFound = aIter.next( aPrefix, aURL );
228     }
229     while( bFound && (aPrefix != aName ) );
230 
231     if( !bFound )
232         throw NoSuchElementException();
233 
234     return makeAny( aURL );
235 }
236 
237 Sequence< ::rtl::OUString > SAL_CALL NamespaceMap::getElementNames() throw (RuntimeException)
238 {
239     NamespaceIteratorImpl aIter( mpWhichIds, mpPool );
240 
241     ::rtl::OUString aPrefix;
242     ::rtl::OUString aURL;
243 
244     std::set< ::rtl::OUString, comphelper::UStringLess > aPrefixSet;
245 
246     while( aIter.next( aPrefix, aURL ) )
247         aPrefixSet.insert( aPrefix );
248 
249     Sequence< ::rtl::OUString > aSeq( aPrefixSet.size() );
250     ::rtl::OUString* pPrefixes = aSeq.getArray();
251 
252     std::set< ::rtl::OUString, comphelper::UStringLess >::iterator aPrefixIter( aPrefixSet.begin() );
253     const std::set< ::rtl::OUString, comphelper::UStringLess >::iterator aEnd( aPrefixSet.end() );
254 
255     while( aPrefixIter != aEnd )
256     {
257         *pPrefixes++ = *aPrefixIter++;
258     }
259 
260     return aSeq;
261 }
262 
263 sal_Bool SAL_CALL NamespaceMap::hasByName( const ::rtl::OUString& aName ) throw (RuntimeException)
264 {
265     NamespaceIteratorImpl aIter( mpWhichIds, mpPool );
266 
267     ::rtl::OUString aPrefix;
268     ::rtl::OUString aURL;
269 
270     sal_Bool bFound;
271 
272     do
273     {
274         bFound = aIter.next( aPrefix, aURL );
275     }
276     while( bFound && (aPrefix != aName ) );
277 
278     return bFound;
279 }
280 
281 // XElementAccess
282 Type SAL_CALL NamespaceMap::getElementType() throw (RuntimeException)
283 {
284     return ::getCppuType( (const ::rtl::OUString*) 0 );
285 }
286 
287 sal_Bool SAL_CALL NamespaceMap::hasElements() throw (RuntimeException)
288 {
289     NamespaceIteratorImpl aIter( mpWhichIds, mpPool );
290 
291     ::rtl::OUString aPrefix;
292     ::rtl::OUString aURL;
293 
294     return aIter.next( aPrefix, aURL );
295 }
296 
297 // XServiceInfo
298 ::rtl::OUString SAL_CALL NamespaceMap::getImplementationName(  )
299     throw(RuntimeException)
300 {
301     return NamespaceMap_getImplementationName();
302 }
303 
304 sal_Bool SAL_CALL NamespaceMap::supportsService( const ::rtl::OUString& )
305     throw(RuntimeException)
306 {
307     return sal_True;
308 }
309 
310 Sequence< ::rtl::OUString > SAL_CALL NamespaceMap::getSupportedServiceNames(  )
311     throw(RuntimeException)
312 {
313     return NamespaceMap_getSupportedServiceNames();
314 }
315