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