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