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 84 Reference< XInterface > SAL_CALL NamespaceMap_createInstance( sal_uInt16* pWhichIds, SfxItemPool* pPool1, SfxItemPool* ) 85 { 86 return (XWeak*)new NamespaceMap( pWhichIds, pPool1 ); 87 } 88 89 Reference< XInterface > SAL_CALL NamespaceMap_createInstance( sal_uInt16* pWhichIds, SfxItemPool* pPool ) 90 { 91 return (XWeak*)new NamespaceMap( pWhichIds, pPool ); 92 } 93 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 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 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 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 202 NamespaceMap::NamespaceMap( sal_uInt16* pWhichIds, SfxItemPool* pPool ) 203 : mpWhichIds( pWhichIds ), mpPool( pPool ) 204 { 205 } 206 207 NamespaceMap::~NamespaceMap() 208 { 209 } 210 211 // XNameAccess 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 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 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 278 Type SAL_CALL NamespaceMap::getElementType() throw (RuntimeException) 279 { 280 return ::getCppuType( (const ::rtl::OUString*) 0 ); 281 } 282 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 294 ::rtl::OUString SAL_CALL NamespaceMap::getImplementationName( ) 295 throw(RuntimeException) 296 { 297 return NamespaceMap_getImplementationName(); 298 } 299 300 sal_Bool SAL_CALL NamespaceMap::supportsService( const ::rtl::OUString& ) 301 throw(RuntimeException) 302 { 303 return sal_True; 304 } 305 306 Sequence< ::rtl::OUString > SAL_CALL NamespaceMap::getSupportedServiceNames( ) 307 throw(RuntimeException) 308 { 309 return NamespaceMap_getSupportedServiceNames(); 310 } 311