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_xmloff.hxx" 30 #include <tools/debug.hxx> 31 #include <com/sun/star/xml/AttributeData.hpp> 32 #include <rtl/ustrbuf.hxx> 33 #include <rtl/uuid.h> 34 #include <rtl/memory.h> 35 36 #include <xmloff/xmlcnimp.hxx> 37 38 #include "xmloff/unoatrcn.hxx" 39 40 using ::rtl::OUString; 41 using ::rtl::OUStringBuffer; 42 43 using namespace ::com::sun::star; 44 45 // -------------------------------------------------------------------- 46 // Interface implementation 47 // -------------------------------------------------------------------- 48 49 #define IMPL ((AttrContainerImpl*)mpData) 50 51 uno::Reference< uno::XInterface > SvUnoAttributeContainer_CreateInstance() 52 { 53 return *(new SvUnoAttributeContainer); 54 } 55 56 SvUnoAttributeContainer::SvUnoAttributeContainer( SvXMLAttrContainerData* pContainer) 57 : mpContainer( pContainer ) 58 { 59 if( mpContainer == NULL ) 60 mpContainer = new SvXMLAttrContainerData; 61 } 62 63 SvUnoAttributeContainer::~SvUnoAttributeContainer() 64 { 65 delete mpContainer; 66 } 67 68 // container::XElementAccess 69 uno::Type SAL_CALL SvUnoAttributeContainer::getElementType(void) 70 throw( uno::RuntimeException ) 71 { 72 return ::getCppuType((const xml::AttributeData*)0); 73 } 74 75 sal_Bool SAL_CALL SvUnoAttributeContainer::hasElements(void) 76 throw( uno::RuntimeException ) 77 { 78 return mpContainer->GetAttrCount() != 0; 79 } 80 81 sal_uInt16 SvUnoAttributeContainer::getIndexByName(const OUString& aName ) const 82 { 83 const sal_uInt16 nAttrCount = mpContainer->GetAttrCount(); 84 85 sal_Int32 nPos = aName.indexOf( sal_Unicode(':') ); 86 if( nPos == -1L ) 87 { 88 for( sal_uInt16 nAttr = 0; nAttr < nAttrCount; nAttr++ ) 89 { 90 if( mpContainer->GetAttrLName(nAttr) == aName && 91 mpContainer->GetAttrPrefix(nAttr).getLength() == 0L ) 92 return nAttr; 93 } 94 } 95 else 96 { 97 const OUString aPrefix( aName.copy( 0L, nPos ) ); 98 const OUString aLName( aName.copy( nPos+1L ) ); 99 100 for( sal_uInt16 nAttr = 0; nAttr < nAttrCount; nAttr++ ) 101 { 102 if( mpContainer->GetAttrLName(nAttr) == aLName && 103 mpContainer->GetAttrPrefix(nAttr) == aPrefix ) 104 return nAttr; 105 } 106 } 107 108 return USHRT_MAX; 109 } 110 111 const ::com::sun::star::uno::Sequence< sal_Int8 > & SvUnoAttributeContainer::getUnoTunnelId() throw() 112 { 113 static ::com::sun::star::uno::Sequence< sal_Int8 > * pSeq = 0; 114 if( !pSeq ) 115 { 116 ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ); 117 if( !pSeq ) 118 { 119 static ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( 16 ); 120 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True ); 121 pSeq = &aSeq; 122 } 123 } 124 return *pSeq; 125 } 126 127 SvUnoAttributeContainer* SvUnoAttributeContainer::getImplementation( uno::Reference< uno::XInterface > xInt ) throw() 128 { 129 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xUT( xInt, ::com::sun::star::uno::UNO_QUERY ); 130 if( xUT.is() ) 131 { 132 return 133 reinterpret_cast<SvUnoAttributeContainer*>( 134 sal::static_int_cast<sal_IntPtr>( 135 xUT->getSomething( SvUnoAttributeContainer::getUnoTunnelId()))); 136 } 137 else 138 return NULL; 139 } 140 141 sal_Int64 SAL_CALL SvUnoAttributeContainer::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw(::com::sun::star::uno::RuntimeException) 142 { 143 if( rId.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), 144 rId.getConstArray(), 16 ) ) 145 { 146 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this)); 147 } 148 return 0; 149 } 150 151 // container::XNameAccess 152 uno::Any SAL_CALL SvUnoAttributeContainer::getByName(const OUString& aName) 153 throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException ) 154 { 155 sal_uInt16 nAttr = getIndexByName(aName ); 156 157 if( nAttr == USHRT_MAX ) 158 throw container::NoSuchElementException(); 159 160 xml::AttributeData aData; 161 aData.Namespace = mpContainer->GetAttrNamespace(nAttr); 162 aData.Type = OUString::createFromAscii("CDATA"); 163 aData.Value = mpContainer->GetAttrValue(nAttr); 164 165 uno::Any aAny; 166 aAny <<= aData; 167 return aAny; 168 } 169 170 uno::Sequence< OUString > SAL_CALL SvUnoAttributeContainer::getElementNames(void) throw( uno::RuntimeException ) 171 { 172 const sal_uInt16 nAttrCount = mpContainer->GetAttrCount(); 173 174 uno::Sequence< OUString > aElementNames( (sal_Int32)nAttrCount ); 175 OUString *pNames = aElementNames.getArray(); 176 177 for( sal_uInt16 nAttr = 0; nAttr < nAttrCount; nAttr++ ) 178 { 179 OUStringBuffer sBuffer( mpContainer->GetAttrPrefix(nAttr) ); 180 if( sBuffer.getLength() != 0L ) 181 sBuffer.append( (sal_Unicode)':' ); 182 sBuffer.append( mpContainer->GetAttrLName(nAttr) ); 183 *pNames++ = sBuffer.makeStringAndClear(); 184 } 185 186 return aElementNames; 187 } 188 189 sal_Bool SAL_CALL SvUnoAttributeContainer::hasByName(const OUString& aName) throw( uno::RuntimeException ) 190 { 191 return getIndexByName(aName ) != USHRT_MAX; 192 } 193 194 // container::XNameReplace 195 void SAL_CALL SvUnoAttributeContainer::replaceByName(const OUString& aName, const uno::Any& aElement) 196 throw( lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException ) 197 { 198 if( aElement.hasValue() && aElement.getValueType() == ::getCppuType((const xml::AttributeData*)0) ) 199 { 200 sal_uInt16 nAttr = getIndexByName(aName ); 201 if( nAttr == USHRT_MAX ) 202 throw container::NoSuchElementException(); 203 204 xml::AttributeData* pData = (xml::AttributeData*)aElement.getValue(); 205 206 sal_Int32 nPos = aName.indexOf( sal_Unicode(':') ); 207 if( nPos != -1L ) 208 { 209 const OUString aPrefix( aName.copy( 0L, nPos )); 210 const OUString aLName( aName.copy( nPos+1L )); 211 212 if( pData->Namespace.getLength() == 0L ) 213 { 214 if( mpContainer->SetAt( nAttr, aPrefix, aLName, pData->Value ) ) 215 return; 216 } 217 else 218 { 219 if( mpContainer->SetAt( nAttr, aPrefix, pData->Namespace, aLName, pData->Value ) ) 220 return; 221 } 222 } 223 else 224 { 225 if( pData->Namespace.getLength() == 0L ) 226 { 227 if( mpContainer->SetAt( nAttr, aName, pData->Value ) ) 228 return; 229 } 230 } 231 } 232 233 throw lang::IllegalArgumentException(); 234 } 235 236 // container::XNameContainer 237 void SAL_CALL SvUnoAttributeContainer::insertByName(const OUString& aName, const uno::Any& aElement) 238 throw( lang::IllegalArgumentException, container::ElementExistException, lang::WrappedTargetException, uno::RuntimeException ) 239 { 240 if( !aElement.hasValue() || aElement.getValueType() != ::getCppuType((const xml::AttributeData*)0) ) 241 throw lang::IllegalArgumentException(); 242 243 sal_uInt16 nAttr = getIndexByName(aName ); 244 if( nAttr != USHRT_MAX ) 245 throw container::ElementExistException(); 246 247 xml::AttributeData* pData = (xml::AttributeData*)aElement.getValue(); 248 249 sal_Int32 nPos = aName.indexOf( sal_Unicode(':') ); 250 if( nPos != -1L ) 251 { 252 const OUString aPrefix( aName.copy( 0L, nPos )); 253 const OUString aLName( aName.copy( nPos+1L )); 254 255 if( pData->Namespace.getLength() == 0L ) 256 { 257 if( mpContainer->AddAttr( aPrefix, aLName, pData->Value ) ) 258 return; 259 } 260 else 261 { 262 if( mpContainer->AddAttr( aPrefix, pData->Namespace, aLName, pData->Value ) ) 263 return; 264 } 265 } 266 else 267 { 268 if( pData->Namespace.getLength() == 0L ) 269 { 270 if( mpContainer->AddAttr( aName, pData->Value ) ) 271 return; 272 } 273 } 274 } 275 276 void SAL_CALL SvUnoAttributeContainer::removeByName(const OUString& Name) 277 throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException ) 278 { 279 sal_uInt16 nAttr = getIndexByName(Name); 280 if( nAttr == USHRT_MAX ) 281 throw container::NoSuchElementException(); 282 283 mpContainer->Remove( nAttr ); 284 } 285 286 //XServiceInfo 287 OUString SAL_CALL SvUnoAttributeContainer::getImplementationName(void) throw( uno::RuntimeException ) 288 { 289 return OUString::createFromAscii( "SvUnoAttributeContainer" ); 290 } 291 292 uno::Sequence< OUString > SvUnoAttributeContainer::getSupportedServiceNames(void) 293 throw( uno::RuntimeException ) 294 { 295 OUString aSN( OUString::createFromAscii( "com.sun.star.xml.AttributeContainer" ) ); 296 uno::Sequence< OUString > aNS( &aSN, 1L ); 297 return aNS; 298 } 299 300 sal_Bool SvUnoAttributeContainer::supportsService(const OUString& ServiceName) 301 throw( uno::RuntimeException ) 302 { 303 const uno::Sequence < OUString > aServiceNames( getSupportedServiceNames() ); 304 const OUString* pNames = aServiceNames.getConstArray(); 305 sal_Int32 nCount = aServiceNames.getLength(); 306 while( nCount-- ) 307 { 308 if( *pNames++ == ServiceName ) 309 return sal_True; 310 } 311 312 return sal_False; 313 } 314 315 316