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