LibreOffice Module svx (master)  1
UnoNamespaceMap.cxx
Go to the documentation of this file.
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 <climits>
22 #include <set>
23 
24 #include <svx/UnoNamespaceMap.hxx>
25 #include <com/sun/star/container/XNameAccess.hpp>
26 #include <com/sun/star/lang/XServiceInfo.hpp>
27 
28 #include <comphelper/sequence.hxx>
29 #include <cppuhelper/implbase.hxx>
31 #include <svl/itempool.hxx>
32 #include <editeng/xmlcnitm.hxx>
33 
34 using namespace ::cppu;
35 using namespace ::com::sun::star;
36 using namespace ::com::sun::star::uno;
37 using namespace ::com::sun::star::container;
38 using namespace ::com::sun::star::lang;
39 
40 namespace svx
41 {
42  namespace {
43 
47  class NamespaceMap : public WeakImplHelper< XNameAccess, XServiceInfo >
48  {
49  private:
50  sal_uInt16* mpWhichIds;
51  SfxItemPool* mpPool;
52 
53  public:
54  NamespaceMap( sal_uInt16* pWhichIds, SfxItemPool* pPool );
55 
56  // XNameAccess
57  virtual Any SAL_CALL getByName( const OUString& aName ) override;
58  virtual Sequence< OUString > SAL_CALL getElementNames( ) override;
59  virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override;
60 
61  // XElementAccess
62  virtual Type SAL_CALL getElementType( ) override;
63  virtual sal_Bool SAL_CALL hasElements( ) override;
64 
65  // XServiceInfo
66  virtual OUString SAL_CALL getImplementationName( ) override;
67  virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
68  virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override;
69  };
70 
71  }
72 
74  {
75  return static_cast<XWeak*>(new NamespaceMap( pWhichIds, pPool ));
76  }
77 
79  throw()
80  {
81  Sequence<OUString> aSupportedServiceNames { "com.sun.star.xml.NamespaceMap" };
82  return aSupportedServiceNames;
83  }
84 
86  throw()
87  {
88  return "com.sun.star.comp.Svx.NamespaceMap";
89  }
90 
91  namespace {
92 
93  class NamespaceIteratorImpl
94  {
95  private:
96  SfxItemPool* mpPool;
97 
98  sal_uInt16* mpWhichId;
99 
100  std::vector<const SvXMLAttrContainerItem*> mvItems;
101  sal_Int32 mnItem;
102 
103  const SvXMLAttrContainerItem* mpCurrentAttr;
104  sal_uInt16 mnCurrentAttr;
105 
106  public:
107 
108  NamespaceIteratorImpl( sal_uInt16* pWhichIds, SfxItemPool* pPool );
109 
110  bool next( OUString& rPrefix, OUString& rURL );
111  };
112 
113  }
114 }
115 
116 using namespace ::svx;
117 
118 
119 NamespaceIteratorImpl::NamespaceIteratorImpl( sal_uInt16* pWhichIds, SfxItemPool* pPool )
120 {
121  mpPool = pPool;
122  mpCurrentAttr = nullptr;
123  mnCurrentAttr = 0;
124 
125  mpWhichId = pWhichIds;
126 
127  mnItem = -1;
128  if (mpWhichId && (0 != *mpWhichId) && mpPool)
129  {
130  mvItems.reserve(mpPool->GetItemCount2( *mpWhichId ));
131  for (const SfxPoolItem* pItem : mpPool->GetItemSurrogates( *mpWhichId ))
132  mvItems.push_back(static_cast<const SvXMLAttrContainerItem*>(pItem));
133  }
134 }
135 
136 bool NamespaceIteratorImpl::next( OUString& rPrefix, OUString& rURL )
137 {
138  // we still need to process the current attribute
139  if( mpCurrentAttr && (mnCurrentAttr != USHRT_MAX) )
140  {
141  rPrefix = mpCurrentAttr->GetPrefix( mnCurrentAttr );
142  rURL = mpCurrentAttr->GetNamespace( mnCurrentAttr );
143 
144  mnCurrentAttr = mpCurrentAttr->GetNextNamespaceIndex( mnCurrentAttr );
145  return true;
146  }
147 
148  // we need the next namespace item
149  mpCurrentAttr = nullptr;
150  mnItem++;
151 
152  // are we finished with the current whichid?
153  if( mnItem == static_cast<sal_Int32>(mvItems.size()) )
154  {
155  mpWhichId++;
156 
157  // are we finished with the current pool?
158  if( 0 == *mpWhichId )
159  return false;
160 
161  mnItem = -1;
162  mvItems.clear();
163  if (mpPool)
164  {
165  mvItems.reserve(mpPool->GetItemCount2( *mpWhichId ));
166  for (const SfxPoolItem* pItem2 : mpPool->GetItemSurrogates( *mpWhichId ))
167  mvItems.push_back(static_cast<const SvXMLAttrContainerItem*>(pItem2));
168  }
169  return next( rPrefix, rURL );
170  }
171 
172  auto pItem = mvItems[mnItem];
173  // get that item and see if there namespaces inside
174  if( pItem->GetAttrCount() > 0 )
175  {
176  mpCurrentAttr = pItem;
177  mnCurrentAttr = pItem->GetFirstNamespaceIndex();
178  }
179  return next( rPrefix, rURL );
180 }
181 
182 
183 NamespaceMap::NamespaceMap( sal_uInt16* pWhichIds, SfxItemPool* pPool )
184 : mpWhichIds( pWhichIds ), mpPool( pPool )
185 {
186 }
187 
188 // XNameAccess
189 Any SAL_CALL NamespaceMap::getByName( const OUString& aName )
190 {
191  NamespaceIteratorImpl aIter( mpWhichIds, mpPool );
192 
193  OUString aPrefix;
194  OUString aURL;
195 
196  bool bFound;
197 
198  do
199  {
200  bFound = aIter.next( aPrefix, aURL );
201  }
202  while( bFound && (aPrefix != aName ) );
203 
204  if( !bFound )
205  throw NoSuchElementException();
206 
207  return makeAny( aURL );
208 }
209 
210 Sequence< OUString > SAL_CALL NamespaceMap::getElementNames()
211 {
212  NamespaceIteratorImpl aIter( mpWhichIds, mpPool );
213 
214  OUString aPrefix;
215  OUString aURL;
216 
217  std::set< OUString > aPrefixSet;
218 
219  while( aIter.next( aPrefix, aURL ) )
220  aPrefixSet.insert( aPrefix );
221 
222  return comphelper::containerToSequence(aPrefixSet);
223 }
224 
225 sal_Bool SAL_CALL NamespaceMap::hasByName( const OUString& aName )
226 {
227  NamespaceIteratorImpl aIter( mpWhichIds, mpPool );
228 
229  OUString aPrefix;
230  OUString aURL;
231 
232  bool bFound;
233 
234  do
235  {
236  bFound = aIter.next( aPrefix, aURL );
237  }
238  while( bFound && (aPrefix != aName ) );
239 
240  return bFound;
241 }
242 
243 // XElementAccess
244 Type SAL_CALL NamespaceMap::getElementType()
245 {
246  return ::cppu::UnoType<OUString>::get();
247 }
248 
249 sal_Bool SAL_CALL NamespaceMap::hasElements()
250 {
251  NamespaceIteratorImpl aIter( mpWhichIds, mpPool );
252 
253  OUString aPrefix;
254  OUString aURL;
255 
256  return aIter.next( aPrefix, aURL );
257 }
258 
259 // XServiceInfo
260 OUString SAL_CALL NamespaceMap::getImplementationName( )
261 {
263 }
264 
265 sal_Bool SAL_CALL NamespaceMap::supportsService( const OUString& serviceName )
266 {
267  return cppu::supportsService( this, serviceName );
268 }
269 
270 Sequence< OUString > SAL_CALL NamespaceMap::getSupportedServiceNames( )
271 {
273 }
274 
275 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Type
URL aURL
Reference< XInterface > NamespaceMap_createInstance(sal_uInt16 *pWhichIds, SfxItemPool *pPool)
OUString getImplementationName()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
static Sequence< OUString > NamespaceMap_getSupportedServiceNames()
css::uno::Sequence< OUString > getSupportedServiceNames()
static OUString NamespaceMap_getImplementationName()
unsigned char sal_Bool
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
css::uno::Any SAL_CALL makeAny(const SharedUNOComponent< INTERFACE, COMPONENT > &value)