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 "EventOASISTContext.hxx" 27 #include "EventMap.hxx" 28 #include "MutableAttrList.hxx" 29 #include "xmloff/xmlnmspe.hxx" 30 #include "ActionMapTypesOASIS.hxx" 31 #include "AttrTransformerAction.hxx" 32 #include "TransformerActions.hxx" 33 #ifndef _XMLOFF_TRANSFORMERBASE_HXX 34 #include "TransformerBase.hxx" 35 #endif 36 37 #ifndef OASIS_FILTER_OOO_1X 38 // Used to parse Scripting Framework URLs 39 #include <com/sun/star/uri/XUriReferenceFactory.hpp> 40 #include <com/sun/star/uri/XVndSunStarScriptUrl.hpp> 41 #include <comphelper/processfactory.hxx> 42 #endif 43 44 #include <hash_map> 45 46 using ::rtl::OUString; 47 48 using namespace ::com::sun::star::uno; 49 using namespace ::com::sun::star::xml::sax; 50 using namespace ::xmloff::token; 51 52 class XMLTransformerOASISEventMap_Impl: 53 public ::std::hash_map< NameKey_Impl, ::rtl::OUString, 54 NameHash_Impl, NameHash_Impl > 55 { 56 public: 57 XMLTransformerOASISEventMap_Impl( XMLTransformerEventMapEntry *pInit ); 58 ~XMLTransformerOASISEventMap_Impl(); 59 }; 60 61 XMLTransformerOASISEventMap_Impl::XMLTransformerOASISEventMap_Impl( XMLTransformerEventMapEntry *pInit ) 62 { 63 if( pInit ) 64 { 65 XMLTransformerOASISEventMap_Impl::key_type aKey; 66 XMLTransformerOASISEventMap_Impl::data_type aData; 67 while( pInit->m_pOASISName ) 68 { 69 aKey.m_nPrefix = pInit->m_nOASISPrefix; 70 aKey.m_aLocalName = OUString::createFromAscii(pInit->m_pOASISName); 71 72 OSL_ENSURE( find( aKey ) == end(), "duplicate event map entry" ); 73 74 aData = OUString::createFromAscii(pInit->m_pOOoName); 75 76 XMLTransformerOASISEventMap_Impl::value_type aVal( aKey, aData ); 77 78 insert( aVal ); 79 ++pInit; 80 } 81 } 82 } 83 84 XMLTransformerOASISEventMap_Impl::~XMLTransformerOASISEventMap_Impl() 85 { 86 } 87 88 // ----------------------------------------------------------------------------- 89 90 TYPEINIT1( XMLEventOASISTransformerContext, XMLRenameElemTransformerContext); 91 92 XMLEventOASISTransformerContext::XMLEventOASISTransformerContext( 93 XMLTransformerBase& rImp, 94 const OUString& rQName ) : 95 XMLRenameElemTransformerContext( rImp, rQName, 96 rImp.GetNamespaceMap().GetKeyByAttrName( rQName ), XML_EVENT ) 97 { 98 } 99 100 XMLEventOASISTransformerContext::~XMLEventOASISTransformerContext() 101 { 102 } 103 104 XMLTransformerOASISEventMap_Impl 105 *XMLEventOASISTransformerContext::CreateEventMap() 106 { 107 return new XMLTransformerOASISEventMap_Impl( aTransformerEventMap ); 108 } 109 110 XMLTransformerOASISEventMap_Impl 111 *XMLEventOASISTransformerContext::CreateFormEventMap() 112 { 113 return new XMLTransformerOASISEventMap_Impl( aFormTransformerEventMap ); 114 } 115 116 void XMLEventOASISTransformerContext::FlushEventMap( 117 XMLTransformerOASISEventMap_Impl *p ) 118 { 119 delete p; 120 } 121 122 OUString XMLEventOASISTransformerContext::GetEventName( 123 sal_uInt16 nPrefix, 124 const OUString& rName, 125 XMLTransformerOASISEventMap_Impl& rMap, 126 XMLTransformerOASISEventMap_Impl *pMap2) 127 { 128 XMLTransformerOASISEventMap_Impl::key_type aKey( nPrefix, rName ); 129 if( pMap2 ) 130 { 131 XMLTransformerOASISEventMap_Impl::const_iterator aIter = 132 pMap2->find( aKey ); 133 if( !(aIter == pMap2->end()) ) 134 return (*aIter).second; 135 } 136 137 XMLTransformerOASISEventMap_Impl::const_iterator aIter = rMap.find( aKey ); 138 if( aIter == rMap.end() ) 139 return rName; 140 else 141 return (*aIter).second; 142 } 143 144 bool ParseURLAsString( 145 const OUString& rAttrValue, 146 OUString* pName, OUString* pLocation ) 147 { 148 OUString SCHEME( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.script:" ) ); 149 150 sal_Int32 params = rAttrValue.indexOf( '?' ); 151 if ( rAttrValue.indexOf( SCHEME ) != 0 || params < 0 ) 152 { 153 return sal_False; 154 } 155 156 sal_Int32 start = SCHEME.getLength(); 157 *pName = rAttrValue.copy( start, params - start ); 158 159 OUString aToken; 160 OUString aLanguage; 161 params++; 162 do 163 { 164 aToken = rAttrValue.getToken( 0, '&', params ); 165 sal_Int32 dummy = 0; 166 167 if ( aToken.match( GetXMLToken( XML_LANGUAGE ) ) ) 168 { 169 aLanguage = aToken.getToken( 1, '=', dummy ); 170 } 171 else if ( aToken.match( GetXMLToken( XML_LOCATION ) ) ) 172 { 173 OUString tmp = aToken.getToken( 1, '=', dummy ); 174 if ( tmp.equalsIgnoreAsciiCase( GetXMLToken( XML_DOCUMENT ) ) ) 175 { 176 *pLocation = GetXMLToken( XML_DOCUMENT ); 177 } 178 else 179 { 180 *pLocation = GetXMLToken( XML_APPLICATION ); 181 } 182 } 183 } while ( params >= 0 ); 184 185 if ( aLanguage.equalsIgnoreAsciiCaseAscii( "basic" ) ) 186 { 187 return sal_True; 188 } 189 return sal_False; 190 } 191 192 bool ParseURL( 193 const OUString& rAttrValue, 194 OUString* pName, OUString* pLocation ) 195 { 196 #ifdef OASIS_FILTER_OOO_1X 197 return ParseURLAsString( rAttrValue, pName, pLocation ); 198 #else 199 Reference< com::sun::star::lang::XMultiServiceFactory > 200 xSMgr = ::comphelper::getProcessServiceFactory(); 201 202 Reference< com::sun::star::uri::XUriReferenceFactory > 203 xFactory( xSMgr->createInstance( OUString::createFromAscii( 204 "com.sun.star.uri.UriReferenceFactory" ) ), UNO_QUERY ); 205 206 if ( xFactory.is() ) 207 { 208 Reference< com::sun::star::uri::XVndSunStarScriptUrl > xUrl ( 209 xFactory->parse( rAttrValue ), UNO_QUERY ); 210 211 if ( xUrl.is() ) 212 { 213 OUString aLanguageKey = GetXMLToken( XML_LANGUAGE ); 214 if ( xUrl.is() && xUrl->hasParameter( aLanguageKey ) ) 215 { 216 OUString aLanguage = xUrl->getParameter( aLanguageKey ); 217 218 if ( aLanguage.equalsIgnoreAsciiCaseAscii( "basic" ) ) 219 { 220 *pName = xUrl->getName(); 221 222 OUString tmp = 223 xUrl->getParameter( GetXMLToken( XML_LOCATION ) ); 224 225 OUString doc = GetXMLToken( XML_DOCUMENT ); 226 227 if ( tmp.equalsIgnoreAsciiCase( doc ) ) 228 { 229 *pLocation = doc; 230 } 231 else 232 { 233 *pLocation = GetXMLToken( XML_APPLICATION ); 234 } 235 return sal_True; 236 } 237 } 238 } 239 return sal_False; 240 } 241 else 242 { 243 return ParseURLAsString( rAttrValue, pName, pLocation ); 244 } 245 #endif 246 } 247 248 void XMLEventOASISTransformerContext::StartElement( 249 const Reference< XAttributeList >& rAttrList ) 250 { 251 OSL_TRACE("XMLEventOASISTransformerContext::StartElement"); 252 253 XMLTransformerActions *pActions = 254 GetTransformer().GetUserDefinedActions( OASIS_EVENT_ACTIONS ); 255 OSL_ENSURE( pActions, "go no actions" ); 256 257 Reference< XAttributeList > xAttrList( rAttrList ); 258 XMLMutableAttributeList *pMutableAttrList = 0; 259 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; 260 for( sal_Int16 i=0; i < nAttrCount; i++ ) 261 { 262 const OUString& rAttrName = xAttrList->getNameByIndex( i ); 263 OUString aLocalName; 264 sal_uInt16 nPrefix = 265 GetTransformer().GetNamespaceMap().GetKeyByAttrName( rAttrName, 266 &aLocalName ); 267 XMLTransformerActions::key_type aKey( nPrefix, aLocalName ); 268 XMLTransformerActions::const_iterator aIter = 269 pActions->find( aKey ); 270 if( !(aIter == pActions->end() ) ) 271 { 272 if( !pMutableAttrList ) 273 { 274 pMutableAttrList = 275 new XMLMutableAttributeList( xAttrList ); 276 xAttrList = pMutableAttrList; 277 } 278 const OUString& rAttrValue = xAttrList->getValueByIndex( i ); 279 switch( (*aIter).second.m_nActionType ) 280 { 281 case XML_ATACTION_HREF: 282 { 283 OUString aAttrValue( rAttrValue ); 284 OUString aName, aLocation; 285 286 bool bNeedsTransform = 287 ParseURL( rAttrValue, &aName, &aLocation ); 288 289 if ( bNeedsTransform ) 290 { 291 pMutableAttrList->RemoveAttributeByIndex( i ); 292 293 OUString aAttrQName( 294 GetTransformer().GetNamespaceMap().GetQNameByKey( 295 XML_NAMESPACE_SCRIPT, 296 ::xmloff::token::GetXMLToken( XML_MACRO_NAME ) ) ); 297 298 pMutableAttrList->AddAttribute( aAttrQName, aName ); 299 300 sal_Int16 idx = pMutableAttrList->GetIndexByName( 301 GetTransformer().GetNamespaceMap().GetQNameByKey( 302 XML_NAMESPACE_SCRIPT, 303 GetXMLToken( XML_LANGUAGE ) ) ); 304 305 pMutableAttrList->SetValueByIndex( idx, 306 OUString::createFromAscii("StarBasic") ); 307 308 OUString aLocQName( 309 GetTransformer().GetNamespaceMap().GetQNameByKey( 310 XML_NAMESPACE_SCRIPT, 311 GetXMLToken( XML_LOCATION ) ) ); 312 313 pMutableAttrList->AddAttribute( aLocQName, aLocation ); 314 } 315 } 316 break; 317 case XML_ATACTION_EVENT_NAME: 318 { 319 // Check if the event belongs to a form or control by 320 // cehcking the 2nd ancestor element, f.i.: 321 // <form:button><form:event-listeners><form:event-listener> 322 const XMLTransformerContext *pObjContext = 323 GetTransformer().GetAncestorContext( 1 ); 324 sal_Bool bForm = pObjContext && 325 326 pObjContext->HasNamespace(XML_NAMESPACE_FORM ); 327 pMutableAttrList->SetValueByIndex( i, 328 GetTransformer().GetEventName( rAttrValue, 329 bForm ) ); 330 } 331 break; 332 case XML_ATACTION_REMOVE_NAMESPACE_PREFIX: 333 { 334 OUString aAttrValue( rAttrValue ); 335 sal_uInt16 nValPrefix = 336 static_cast<sal_uInt16>((*aIter).second.m_nParam1); 337 if( GetTransformer().RemoveNamespacePrefix( 338 aAttrValue, nValPrefix ) ) 339 pMutableAttrList->SetValueByIndex( i, aAttrValue ); 340 } 341 break; 342 case XML_ATACTION_MACRO_NAME: 343 { 344 OUString aName, aLocation; 345 bool bNeedsTransform = 346 ParseURL( rAttrValue, &aName, &aLocation ); 347 348 if ( bNeedsTransform ) 349 { 350 pMutableAttrList->SetValueByIndex( i, aName ); 351 352 sal_Int16 idx = pMutableAttrList->GetIndexByName( 353 GetTransformer().GetNamespaceMap().GetQNameByKey( 354 XML_NAMESPACE_SCRIPT, 355 GetXMLToken( XML_LANGUAGE ) ) ); 356 357 pMutableAttrList->SetValueByIndex( idx, 358 OUString::createFromAscii("StarBasic") ); 359 360 OUString aLocQName( 361 GetTransformer().GetNamespaceMap().GetQNameByKey( 362 XML_NAMESPACE_SCRIPT, 363 GetXMLToken( XML_LOCATION ) ) ); 364 365 pMutableAttrList->AddAttribute( aLocQName, aLocation ); 366 } 367 else 368 { 369 const OUString& rApp = GetXMLToken( XML_APPLICATION ); 370 const OUString& rDoc = GetXMLToken( XML_DOCUMENT ); 371 OUString aAttrValue; 372 if( rAttrValue.getLength() > rApp.getLength()+1 && 373 rAttrValue.copy(0,rApp.getLength()). 374 equalsIgnoreAsciiCase( rApp ) && 375 ':' == rAttrValue[rApp.getLength()] ) 376 { 377 aLocation = rApp; 378 aAttrValue = rAttrValue.copy( rApp.getLength()+1 ); 379 } 380 else if( rAttrValue.getLength() > rDoc.getLength()+1 && 381 rAttrValue.copy(0,rDoc.getLength()). 382 equalsIgnoreAsciiCase( rDoc ) && 383 ':' == rAttrValue[rDoc.getLength()] ) 384 { 385 aLocation= rDoc; 386 aAttrValue = rAttrValue.copy( rDoc.getLength()+1 ); 387 } 388 if( aAttrValue.getLength() ) 389 pMutableAttrList->SetValueByIndex( i, 390 aAttrValue ); 391 if( aLocation.getLength() ) 392 { 393 OUString aAttrQName( GetTransformer().GetNamespaceMap(). 394 GetQNameByKey( XML_NAMESPACE_SCRIPT, 395 ::xmloff::token::GetXMLToken( XML_LOCATION ) ) ); 396 pMutableAttrList->AddAttribute( aAttrQName, aLocation ); 397 // draw bug 398 aAttrQName = GetTransformer().GetNamespaceMap(). 399 GetQNameByKey( XML_NAMESPACE_SCRIPT, 400 ::xmloff::token::GetXMLToken( XML_LIBRARY ) ); 401 pMutableAttrList->AddAttribute( aAttrQName, aLocation ); 402 } 403 } 404 } 405 break; 406 case XML_ATACTION_COPY: 407 break; 408 default: 409 OSL_ENSURE( !this, "unknown action" ); 410 break; 411 } 412 } 413 } 414 415 XMLRenameElemTransformerContext::StartElement( xAttrList ); 416 } 417