1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "EventOASISTContext.hxx"
21 #include "EventMap.hxx"
22 #include "MutableAttrList.hxx"
23 #include <xmloff/xmlnmspe.hxx>
24 #include "ActionMapTypesOASIS.hxx"
25 #include "AttrTransformerAction.hxx"
26 #include "TransformerActions.hxx"
27 #include "TransformerBase.hxx"
28 #include <osl/diagnose.h>
30 // Used to parse Scripting Framework URLs
31 #include <com/sun/star/uri/UriReferenceFactory.hpp>
32 #include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
33 #include <comphelper/processfactory.hxx>
35 #include <unordered_map>
37 using namespace ::com::sun::star::uno
;
38 using namespace ::com::sun::star::xml::sax
;
39 using namespace ::xmloff::token
;
41 class XMLTransformerOASISEventMap_Impl
:
42 public std::unordered_map
< NameKey_Impl
, OUString
,
43 NameHash_Impl
, NameHash_Impl
>
46 XMLTransformerOASISEventMap_Impl( XMLTransformerEventMapEntry
*pInit
);
47 ~XMLTransformerOASISEventMap_Impl();
50 XMLTransformerOASISEventMap_Impl::XMLTransformerOASISEventMap_Impl( XMLTransformerEventMapEntry
*pInit
)
54 XMLTransformerOASISEventMap_Impl::key_type aKey
;
55 XMLTransformerOASISEventMap_Impl::mapped_type aData
;
56 while( pInit
->m_pOASISName
)
58 aKey
.m_nPrefix
= pInit
->m_nOASISPrefix
;
59 aKey
.m_aLocalName
= OUString::createFromAscii(pInit
->m_pOASISName
);
61 OSL_ENSURE( find( aKey
) == end(), "duplicate event map entry" );
63 aData
= OUString::createFromAscii(pInit
->m_pOOoName
);
65 XMLTransformerOASISEventMap_Impl::value_type
aVal( aKey
, aData
);
73 XMLTransformerOASISEventMap_Impl::~XMLTransformerOASISEventMap_Impl()
77 TYPEINIT1( XMLEventOASISTransformerContext
, XMLRenameElemTransformerContext
);
79 XMLEventOASISTransformerContext::XMLEventOASISTransformerContext(
80 XMLTransformerBase
& rImp
,
81 const OUString
& rQName
) :
82 XMLRenameElemTransformerContext( rImp
, rQName
,
83 rImp
.GetNamespaceMap().GetKeyByAttrName( rQName
), XML_EVENT
)
87 XMLEventOASISTransformerContext::~XMLEventOASISTransformerContext()
91 XMLTransformerOASISEventMap_Impl
92 *XMLEventOASISTransformerContext::CreateEventMap()
94 return new XMLTransformerOASISEventMap_Impl( aTransformerEventMap
);
97 XMLTransformerOASISEventMap_Impl
98 *XMLEventOASISTransformerContext::CreateFormEventMap()
100 return new XMLTransformerOASISEventMap_Impl( aFormTransformerEventMap
);
103 void XMLEventOASISTransformerContext::FlushEventMap(
104 XMLTransformerOASISEventMap_Impl
*p
)
109 OUString
XMLEventOASISTransformerContext::GetEventName(
111 const OUString
& rName
,
112 XMLTransformerOASISEventMap_Impl
& rMap
,
113 XMLTransformerOASISEventMap_Impl
*pMap2
)
115 XMLTransformerOASISEventMap_Impl::key_type
aKey( nPrefix
, rName
);
118 XMLTransformerOASISEventMap_Impl::const_iterator aIter
=
120 if( !(aIter
== pMap2
->end()) )
121 return (*aIter
).second
;
124 XMLTransformerOASISEventMap_Impl::const_iterator aIter
= rMap
.find( aKey
);
125 if( aIter
== rMap
.end() )
128 return (*aIter
).second
;
132 const OUString
& rAttrValue
,
133 OUString
* pName
, OUString
* pLocation
)
135 Reference
< com::sun::star::uno::XComponentContext
>
136 xContext
= ::comphelper::getProcessComponentContext();
138 Reference
< com::sun::star::uri::XUriReferenceFactory
> xFactory
=
139 com::sun::star::uri::UriReferenceFactory::create(xContext
);
141 Reference
< com::sun::star::uri::XVndSunStarScriptUrl
> xUrl (
142 xFactory
->parse( rAttrValue
), UNO_QUERY
);
146 OUString aLanguageKey
= GetXMLToken( XML_LANGUAGE
);
147 if ( xUrl
.is() && xUrl
->hasParameter( aLanguageKey
) )
149 OUString aLanguage
= xUrl
->getParameter( aLanguageKey
);
151 if ( aLanguage
.equalsIgnoreAsciiCase("basic") )
153 *pName
= xUrl
->getName();
156 xUrl
->getParameter( GetXMLToken( XML_LOCATION
) );
158 OUString doc
= GetXMLToken( XML_DOCUMENT
);
160 if ( tmp
.equalsIgnoreAsciiCase( doc
) )
166 *pLocation
= GetXMLToken( XML_APPLICATION
);
175 void XMLEventOASISTransformerContext::StartElement(
176 const Reference
< XAttributeList
>& rAttrList
)
178 SAL_INFO("xmloff.transform", "XMLEventOASISTransformerContext::StartElement");
180 XMLTransformerActions
*pActions
=
181 GetTransformer().GetUserDefinedActions( OASIS_EVENT_ACTIONS
);
182 SAL_WARN_IF( pActions
== NULL
, "xmloff.transform", "got no actions" );
184 Reference
< XAttributeList
> xAttrList( rAttrList
);
185 XMLMutableAttributeList
*pMutableAttrList
= 0;
186 sal_Int16 nAttrCount
= xAttrList
.is() ? xAttrList
->getLength() : 0;
187 for( sal_Int16 i
=0; i
< nAttrCount
; i
++ )
189 const OUString
& rAttrName
= xAttrList
->getNameByIndex( i
);
192 GetTransformer().GetNamespaceMap().GetKeyByAttrName( rAttrName
,
194 XMLTransformerActions::key_type
aKey( nPrefix
, aLocalName
);
195 XMLTransformerActions::const_iterator aIter
=
196 pActions
->find( aKey
);
197 if( !(aIter
== pActions
->end() ) )
199 if( !pMutableAttrList
)
202 new XMLMutableAttributeList( xAttrList
);
203 xAttrList
= pMutableAttrList
;
205 const OUString
& rAttrValue
= xAttrList
->getValueByIndex( i
);
206 switch( (*aIter
).second
.m_nActionType
)
208 case XML_ATACTION_HREF
:
210 OUString aName
, aLocation
;
212 bool bNeedsTransform
=
213 ParseURL( rAttrValue
, &aName
, &aLocation
);
215 if ( bNeedsTransform
)
217 pMutableAttrList
->RemoveAttributeByIndex( i
);
220 GetTransformer().GetNamespaceMap().GetQNameByKey(
221 XML_NAMESPACE_SCRIPT
,
222 ::xmloff::token::GetXMLToken( XML_MACRO_NAME
) ) );
224 pMutableAttrList
->AddAttribute( aAttrQName
, aName
);
226 sal_Int16 idx
= pMutableAttrList
->GetIndexByName(
227 GetTransformer().GetNamespaceMap().GetQNameByKey(
228 XML_NAMESPACE_SCRIPT
,
229 GetXMLToken( XML_LANGUAGE
) ) );
231 pMutableAttrList
->SetValueByIndex( idx
,
232 OUString("StarBasic") );
235 GetTransformer().GetNamespaceMap().GetQNameByKey(
236 XML_NAMESPACE_SCRIPT
,
237 GetXMLToken( XML_LOCATION
) ) );
239 pMutableAttrList
->AddAttribute( aLocQName
, aLocation
);
243 case XML_ATACTION_EVENT_NAME
:
245 // Check if the event belongs to a form or control by
246 // cehcking the 2nd ancestor element, f.i.:
247 // <form:button><form:event-listeners><form:event-listener>
248 const XMLTransformerContext
*pObjContext
=
249 GetTransformer().GetAncestorContext( 1 );
250 bool bForm
= pObjContext
&&
252 pObjContext
->HasNamespace(XML_NAMESPACE_FORM
);
253 pMutableAttrList
->SetValueByIndex( i
,
254 GetTransformer().GetEventName( rAttrValue
,
258 case XML_ATACTION_REMOVE_NAMESPACE_PREFIX
:
260 OUString
aAttrValue( rAttrValue
);
261 sal_uInt16 nValPrefix
=
262 static_cast<sal_uInt16
>((*aIter
).second
.m_nParam1
);
263 if( GetTransformer().RemoveNamespacePrefix(
264 aAttrValue
, nValPrefix
) )
265 pMutableAttrList
->SetValueByIndex( i
, aAttrValue
);
268 case XML_ATACTION_MACRO_NAME
:
270 OUString aName
, aLocation
;
271 bool bNeedsTransform
=
272 ParseURL( rAttrValue
, &aName
, &aLocation
);
274 if ( bNeedsTransform
)
276 pMutableAttrList
->SetValueByIndex( i
, aName
);
278 sal_Int16 idx
= pMutableAttrList
->GetIndexByName(
279 GetTransformer().GetNamespaceMap().GetQNameByKey(
280 XML_NAMESPACE_SCRIPT
,
281 GetXMLToken( XML_LANGUAGE
) ) );
283 pMutableAttrList
->SetValueByIndex( idx
,
284 OUString("StarBasic") );
287 GetTransformer().GetNamespaceMap().GetQNameByKey(
288 XML_NAMESPACE_SCRIPT
,
289 GetXMLToken( XML_LOCATION
) ) );
291 pMutableAttrList
->AddAttribute( aLocQName
, aLocation
);
295 const OUString
& rApp
= GetXMLToken( XML_APPLICATION
);
296 const OUString
& rDoc
= GetXMLToken( XML_DOCUMENT
);
298 if( rAttrValue
.getLength() > rApp
.getLength()+1 &&
299 rAttrValue
.copy(0,rApp
.getLength()).
300 equalsIgnoreAsciiCase( rApp
) &&
301 ':' == rAttrValue
[rApp
.getLength()] )
304 aAttrValue
= rAttrValue
.copy( rApp
.getLength()+1 );
306 else if( rAttrValue
.getLength() > rDoc
.getLength()+1 &&
307 rAttrValue
.copy(0,rDoc
.getLength()).
308 equalsIgnoreAsciiCase( rDoc
) &&
309 ':' == rAttrValue
[rDoc
.getLength()] )
312 aAttrValue
= rAttrValue
.copy( rDoc
.getLength()+1 );
314 if( !aAttrValue
.isEmpty() )
315 pMutableAttrList
->SetValueByIndex( i
,
317 if( !aLocation
.isEmpty() )
319 OUString
aAttrQName( GetTransformer().GetNamespaceMap().
320 GetQNameByKey( XML_NAMESPACE_SCRIPT
,
321 ::xmloff::token::GetXMLToken( XML_LOCATION
) ) );
322 pMutableAttrList
->AddAttribute( aAttrQName
, aLocation
);
324 aAttrQName
= GetTransformer().GetNamespaceMap().
325 GetQNameByKey( XML_NAMESPACE_SCRIPT
,
326 ::xmloff::token::GetXMLToken( XML_LIBRARY
) );
327 pMutableAttrList
->AddAttribute( aAttrQName
, aLocation
);
332 case XML_ATACTION_COPY
:
335 SAL_WARN( "xmloff.transform", "unknown action" );
341 XMLRenameElemTransformerContext::StartElement( xAttrList
);
344 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */