1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: EventOASISTContext.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_xmloff.hxx"
33 #include "EventOASISTContext.hxx"
34 #include "EventMap.hxx"
35 #include "MutableAttrList.hxx"
36 #include "xmlnmspe.hxx"
37 #include "ActionMapTypesOASIS.hxx"
38 #include "AttrTransformerAction.hxx"
39 #include "TransformerActions.hxx"
40 #ifndef _XMLOFF_TRANSFORMERBASE_HXX
41 #include "TransformerBase.hxx"
44 #ifndef OASIS_FILTER_OOO_1X
45 // Used to parse Scripting Framework URLs
46 #include <com/sun/star/uri/XUriReferenceFactory.hpp>
47 #include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
48 #include <comphelper/processfactory.hxx>
53 using ::rtl::OUString
;
55 using namespace ::com::sun::star::uno
;
56 using namespace ::com::sun::star::xml::sax
;
57 using namespace ::xmloff::token
;
59 class XMLTransformerOASISEventMap_Impl
:
60 public ::std::hash_map
< NameKey_Impl
, ::rtl::OUString
,
61 NameHash_Impl
, NameHash_Impl
>
64 XMLTransformerOASISEventMap_Impl( XMLTransformerEventMapEntry
*pInit
);
65 ~XMLTransformerOASISEventMap_Impl();
68 XMLTransformerOASISEventMap_Impl::XMLTransformerOASISEventMap_Impl( XMLTransformerEventMapEntry
*pInit
)
72 XMLTransformerOASISEventMap_Impl::key_type aKey
;
73 XMLTransformerOASISEventMap_Impl::data_type aData
;
74 while( pInit
->m_pOASISName
)
76 aKey
.m_nPrefix
= pInit
->m_nOASISPrefix
;
77 aKey
.m_aLocalName
= OUString::createFromAscii(pInit
->m_pOASISName
);
79 OSL_ENSURE( find( aKey
) == end(), "duplicate event map entry" );
81 aData
= OUString::createFromAscii(pInit
->m_pOOoName
);
83 XMLTransformerOASISEventMap_Impl::value_type
aVal( aKey
, aData
);
91 XMLTransformerOASISEventMap_Impl::~XMLTransformerOASISEventMap_Impl()
95 // -----------------------------------------------------------------------------
97 TYPEINIT1( XMLEventOASISTransformerContext
, XMLRenameElemTransformerContext
);
99 XMLEventOASISTransformerContext::XMLEventOASISTransformerContext(
100 XMLTransformerBase
& rImp
,
101 const OUString
& rQName
) :
102 XMLRenameElemTransformerContext( rImp
, rQName
,
103 rImp
.GetNamespaceMap().GetKeyByAttrName( rQName
), XML_EVENT
)
107 XMLEventOASISTransformerContext::~XMLEventOASISTransformerContext()
111 XMLTransformerOASISEventMap_Impl
112 *XMLEventOASISTransformerContext::CreateEventMap()
114 return new XMLTransformerOASISEventMap_Impl( aTransformerEventMap
);
117 XMLTransformerOASISEventMap_Impl
118 *XMLEventOASISTransformerContext::CreateFormEventMap()
120 return new XMLTransformerOASISEventMap_Impl( aFormTransformerEventMap
);
123 void XMLEventOASISTransformerContext::FlushEventMap(
124 XMLTransformerOASISEventMap_Impl
*p
)
129 OUString
XMLEventOASISTransformerContext::GetEventName(
131 const OUString
& rName
,
132 XMLTransformerOASISEventMap_Impl
& rMap
,
133 XMLTransformerOASISEventMap_Impl
*pMap2
)
135 XMLTransformerOASISEventMap_Impl::key_type
aKey( nPrefix
, rName
);
138 XMLTransformerOASISEventMap_Impl::const_iterator aIter
=
140 if( !(aIter
== pMap2
->end()) )
141 return (*aIter
).second
;
144 XMLTransformerOASISEventMap_Impl::const_iterator aIter
= rMap
.find( aKey
);
145 if( aIter
== rMap
.end() )
148 return (*aIter
).second
;
151 bool ParseURLAsString(
152 const OUString
& rAttrValue
,
153 OUString
* pName
, OUString
* pLocation
)
155 OUString
SCHEME( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.script:" ) );
157 sal_Int32 params
= rAttrValue
.indexOf( '?' );
158 if ( rAttrValue
.indexOf( SCHEME
) != 0 || params
< 0 )
163 sal_Int32 start
= SCHEME
.getLength();
164 *pName
= rAttrValue
.copy( start
, params
- start
);
171 aToken
= rAttrValue
.getToken( 0, '&', params
);
174 if ( aToken
.match( GetXMLToken( XML_LANGUAGE
) ) )
176 aLanguage
= aToken
.getToken( 1, '=', dummy
);
178 else if ( aToken
.match( GetXMLToken( XML_LOCATION
) ) )
180 OUString tmp
= aToken
.getToken( 1, '=', dummy
);
181 if ( tmp
.equalsIgnoreAsciiCase( GetXMLToken( XML_DOCUMENT
) ) )
183 *pLocation
= GetXMLToken( XML_DOCUMENT
);
187 *pLocation
= GetXMLToken( XML_APPLICATION
);
190 } while ( params
>= 0 );
192 if ( aLanguage
.equalsIgnoreAsciiCaseAscii( "basic" ) )
200 const OUString
& rAttrValue
,
201 OUString
* pName
, OUString
* pLocation
)
203 #ifdef OASIS_FILTER_OOO_1X
204 return ParseURLAsString( rAttrValue
, pName
, pLocation
);
206 Reference
< com::sun::star::lang::XMultiServiceFactory
>
207 xSMgr
= ::comphelper::getProcessServiceFactory();
209 Reference
< com::sun::star::uri::XUriReferenceFactory
>
210 xFactory( xSMgr
->createInstance( OUString::createFromAscii(
211 "com.sun.star.uri.UriReferenceFactory" ) ), UNO_QUERY
);
215 Reference
< com::sun::star::uri::XVndSunStarScriptUrl
> xUrl (
216 xFactory
->parse( rAttrValue
), UNO_QUERY
);
220 OUString aLanguageKey
= GetXMLToken( XML_LANGUAGE
);
221 if ( xUrl
.is() && xUrl
->hasParameter( aLanguageKey
) )
223 OUString aLanguage
= xUrl
->getParameter( aLanguageKey
);
225 if ( aLanguage
.equalsIgnoreAsciiCaseAscii( "basic" ) )
227 *pName
= xUrl
->getName();
230 xUrl
->getParameter( GetXMLToken( XML_LOCATION
) );
232 OUString doc
= GetXMLToken( XML_DOCUMENT
);
234 if ( tmp
.equalsIgnoreAsciiCase( doc
) )
240 *pLocation
= GetXMLToken( XML_APPLICATION
);
250 return ParseURLAsString( rAttrValue
, pName
, pLocation
);
255 void XMLEventOASISTransformerContext::StartElement(
256 const Reference
< XAttributeList
>& rAttrList
)
258 OSL_TRACE("XMLEventOASISTransformerContext::StartElement");
260 XMLTransformerActions
*pActions
=
261 GetTransformer().GetUserDefinedActions( OASIS_EVENT_ACTIONS
);
262 OSL_ENSURE( pActions
, "go no actions" );
264 Reference
< XAttributeList
> xAttrList( rAttrList
);
265 XMLMutableAttributeList
*pMutableAttrList
= 0;
266 sal_Int16 nAttrCount
= xAttrList
.is() ? xAttrList
->getLength() : 0;
267 for( sal_Int16 i
=0; i
< nAttrCount
; i
++ )
269 const OUString
& rAttrName
= xAttrList
->getNameByIndex( i
);
272 GetTransformer().GetNamespaceMap().GetKeyByAttrName( rAttrName
,
274 XMLTransformerActions::key_type
aKey( nPrefix
, aLocalName
);
275 XMLTransformerActions::const_iterator aIter
=
276 pActions
->find( aKey
);
277 if( !(aIter
== pActions
->end() ) )
279 if( !pMutableAttrList
)
282 new XMLMutableAttributeList( xAttrList
);
283 xAttrList
= pMutableAttrList
;
285 const OUString
& rAttrValue
= xAttrList
->getValueByIndex( i
);
286 switch( (*aIter
).second
.m_nActionType
)
288 case XML_ATACTION_HREF
:
290 OUString
aAttrValue( rAttrValue
);
291 OUString aName
, aLocation
;
293 bool bNeedsTransform
=
294 ParseURL( rAttrValue
, &aName
, &aLocation
);
296 if ( bNeedsTransform
)
298 pMutableAttrList
->RemoveAttributeByIndex( i
);
301 GetTransformer().GetNamespaceMap().GetQNameByKey(
302 XML_NAMESPACE_SCRIPT
,
303 ::xmloff::token::GetXMLToken( XML_MACRO_NAME
) ) );
305 pMutableAttrList
->AddAttribute( aAttrQName
, aName
);
307 sal_Int16 idx
= pMutableAttrList
->GetIndexByName(
308 GetTransformer().GetNamespaceMap().GetQNameByKey(
309 XML_NAMESPACE_SCRIPT
,
310 GetXMLToken( XML_LANGUAGE
) ) );
312 pMutableAttrList
->SetValueByIndex( idx
,
313 OUString::createFromAscii("StarBasic") );
316 GetTransformer().GetNamespaceMap().GetQNameByKey(
317 XML_NAMESPACE_SCRIPT
,
318 GetXMLToken( XML_LOCATION
) ) );
320 pMutableAttrList
->AddAttribute( aLocQName
, aLocation
);
324 case XML_ATACTION_EVENT_NAME
:
326 // Check if the event belongs to a form or control by
327 // cehcking the 2nd ancestor element, f.i.:
328 // <form:button><form:event-listeners><form:event-listener>
329 const XMLTransformerContext
*pObjContext
=
330 GetTransformer().GetAncestorContext( 1 );
331 sal_Bool bForm
= pObjContext
&&
333 pObjContext
->HasNamespace(XML_NAMESPACE_FORM
);
334 pMutableAttrList
->SetValueByIndex( i
,
335 GetTransformer().GetEventName( rAttrValue
,
339 case XML_ATACTION_REMOVE_NAMESPACE_PREFIX
:
341 OUString
aAttrValue( rAttrValue
);
342 sal_uInt16 nValPrefix
=
343 static_cast<sal_uInt16
>((*aIter
).second
.m_nParam1
);
344 if( GetTransformer().RemoveNamespacePrefix(
345 aAttrValue
, nValPrefix
) )
346 pMutableAttrList
->SetValueByIndex( i
, aAttrValue
);
349 case XML_ATACTION_MACRO_NAME
:
351 OUString aName
, aLocation
;
352 bool bNeedsTransform
=
353 ParseURL( rAttrValue
, &aName
, &aLocation
);
355 if ( bNeedsTransform
)
357 pMutableAttrList
->SetValueByIndex( i
, aName
);
359 sal_Int16 idx
= pMutableAttrList
->GetIndexByName(
360 GetTransformer().GetNamespaceMap().GetQNameByKey(
361 XML_NAMESPACE_SCRIPT
,
362 GetXMLToken( XML_LANGUAGE
) ) );
364 pMutableAttrList
->SetValueByIndex( idx
,
365 OUString::createFromAscii("StarBasic") );
368 GetTransformer().GetNamespaceMap().GetQNameByKey(
369 XML_NAMESPACE_SCRIPT
,
370 GetXMLToken( XML_LOCATION
) ) );
372 pMutableAttrList
->AddAttribute( aLocQName
, aLocation
);
376 const OUString
& rApp
= GetXMLToken( XML_APPLICATION
);
377 const OUString
& rDoc
= GetXMLToken( XML_DOCUMENT
);
379 if( rAttrValue
.getLength() > rApp
.getLength()+1 &&
380 rAttrValue
.copy(0,rApp
.getLength()).
381 equalsIgnoreAsciiCase( rApp
) &&
382 ':' == rAttrValue
[rApp
.getLength()] )
385 aAttrValue
= rAttrValue
.copy( rApp
.getLength()+1 );
387 else if( rAttrValue
.getLength() > rDoc
.getLength()+1 &&
388 rAttrValue
.copy(0,rDoc
.getLength()).
389 equalsIgnoreAsciiCase( rDoc
) &&
390 ':' == rAttrValue
[rDoc
.getLength()] )
393 aAttrValue
= rAttrValue
.copy( rDoc
.getLength()+1 );
395 if( aAttrValue
.getLength() )
396 pMutableAttrList
->SetValueByIndex( i
,
398 if( aLocation
.getLength() )
400 OUString
aAttrQName( GetTransformer().GetNamespaceMap().
401 GetQNameByKey( XML_NAMESPACE_SCRIPT
,
402 ::xmloff::token::GetXMLToken( XML_LOCATION
) ) );
403 pMutableAttrList
->AddAttribute( aAttrQName
, aLocation
);
405 aAttrQName
= GetTransformer().GetNamespaceMap().
406 GetQNameByKey( XML_NAMESPACE_SCRIPT
,
407 ::xmloff::token::GetXMLToken( XML_LIBRARY
) );
408 pMutableAttrList
->AddAttribute( aAttrQName
, aLocation
);
413 case XML_ATACTION_COPY
:
416 OSL_ENSURE( !this, "unknown action" );
422 XMLRenameElemTransformerContext::StartElement( xAttrList
);