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