LibreOffice Module xmloff (master) 1
EventOASISTContext.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
21#include "EventMap.hxx"
22#include "MutableAttrList.hxx"
27#include "TransformerBase.hxx"
28#include <osl/diagnose.h>
29#include <sal/log.hxx>
30#include <o3tl/string_view.hxx>
31
32// Used to parse Scripting Framework URLs
33#include <com/sun/star/uri/UriReferenceFactory.hpp>
34#include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
36
37#include <unordered_map>
38
39using namespace ::com::sun::star::uno;
40using namespace ::com::sun::star::xml::sax;
41using namespace ::xmloff::token;
42
44 public std::unordered_map< NameKey_Impl, OUString,
45 NameHash_Impl, NameHash_Impl >
46{
47public:
49};
50
52{
53 if( !pInit )
54 return;
55
56 XMLTransformerOASISEventMap_Impl::key_type aKey;
57 XMLTransformerOASISEventMap_Impl::mapped_type aData;
58 while( pInit->m_pOASISName )
59 {
60 aKey.m_nPrefix = pInit->m_nOASISPrefix;
61 aKey.m_aLocalName = OUString::createFromAscii(pInit->m_pOASISName);
62
63 OSL_ENSURE( find( aKey ) == end(), "duplicate event map entry" );
64
65 aData = OUString::createFromAscii(pInit->m_pOOoName);
66
67 XMLTransformerOASISEventMap_Impl::value_type aVal( aKey, aData );
68
69 insert( aVal );
70 ++pInit;
71 }
72}
73
76 const OUString& rQName ) :
78 rImp.GetNamespaceMap().GetKeyByAttrName( rQName ), XML_EVENT )
79{
80}
81
83{
84}
85
88{
90}
91
94{
96}
97
100{
101 delete p;
102}
103
105 sal_uInt16 nPrefix,
106 const OUString& rName,
109{
110 XMLTransformerOASISEventMap_Impl::key_type aKey( nPrefix, rName );
111 if( pMap2 )
112 {
113 XMLTransformerOASISEventMap_Impl::const_iterator aIter =
114 pMap2->find( aKey );
115 if( aIter != pMap2->end() )
116 return (*aIter).second;
117 }
118
119 XMLTransformerOASISEventMap_Impl::const_iterator aIter = rMap.find( aKey );
120 if( aIter == rMap.end() )
121 return rName;
122 else
123 return (*aIter).second;
124}
125
126static bool ParseURL(
127 const OUString& rAttrValue,
128 OUString* pName, OUString* pLocation )
129{
130 Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
131
132 Reference< css::uri::XUriReferenceFactory > xFactory = css::uri::UriReferenceFactory::create(xContext);
133
134 Reference< css::uri::XVndSunStarScriptUrl > xUrl ( xFactory->parse( rAttrValue ), UNO_QUERY );
135
136 if ( xUrl.is() )
137 {
138 const OUString& aLanguageKey = GetXMLToken( XML_LANGUAGE );
139 if ( xUrl.is() && xUrl->hasParameter( aLanguageKey ) )
140 {
141 OUString aLanguage = xUrl->getParameter( aLanguageKey );
142
143 if ( aLanguage.equalsIgnoreAsciiCase("basic") )
144 {
145 *pName = xUrl->getName();
146
147 OUString tmp =
148 xUrl->getParameter( GetXMLToken( XML_LOCATION ) );
149
150 const OUString& doc = GetXMLToken( XML_DOCUMENT );
151
152 if ( tmp.equalsIgnoreAsciiCase( doc ) )
153 {
154 *pLocation = doc;
155 }
156 else
157 {
158 *pLocation = GetXMLToken( XML_APPLICATION );
159 }
160 return true;
161 }
162 }
163 }
164 return false;
165}
166
168 const Reference< XAttributeList >& rAttrList )
169{
170 SAL_INFO("xmloff.transform", "XMLEventOASISTransformerContext::StartElement");
171
172 XMLTransformerActions *pActions =
174 SAL_WARN_IF( pActions == nullptr, "xmloff.transform", "got no actions" );
175
176 Reference< XAttributeList > xAttrList( rAttrList );
178 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
179 for( sal_Int16 i=0; i < nAttrCount; i++ )
180 {
181 const OUString& rAttrName = xAttrList->getNameByIndex( i );
182 OUString aLocalName;
183 sal_uInt16 nPrefix =
185 &aLocalName );
186 XMLTransformerActions::key_type aKey( nPrefix, aLocalName );
187 XMLTransformerActions::const_iterator aIter =
188 pActions->find( aKey );
189 if( aIter != pActions->end() )
190 {
191 if( !pMutableAttrList )
192 {
193 pMutableAttrList =
194 new XMLMutableAttributeList( xAttrList );
195 xAttrList = pMutableAttrList;
196 }
197 const OUString& rAttrValue = xAttrList->getValueByIndex( i );
198 switch( (*aIter).second.m_nActionType )
199 {
201 {
202 OUString aName, aLocation;
203
204 bool bNeedsTransform =
205 ParseURL( rAttrValue, &aName, &aLocation );
206
207 if ( bNeedsTransform )
208 {
209 pMutableAttrList->RemoveAttributeByIndex( i );
210
211 OUString aAttrQName(
212 GetTransformer().GetNamespaceMap().GetQNameByKey(
215
216 pMutableAttrList->AddAttribute( aAttrQName, aName );
217
218 sal_Int16 idx = pMutableAttrList->GetIndexByName(
219 GetTransformer().GetNamespaceMap().GetQNameByKey(
222
223 if (idx != -1)
224 pMutableAttrList->SetValueByIndex(idx, "StarBasic");
225
226 OUString aLocQName(
227 GetTransformer().GetNamespaceMap().GetQNameByKey(
230
231 pMutableAttrList->AddAttribute( aLocQName, aLocation );
232 }
233 }
234 break;
236 {
237 // Check if the event belongs to a form or control by
238 // checking the 2nd ancestor element, f.i.:
239 // <form:button><form:event-listeners><form:event-listener>
240 const XMLTransformerContext *pObjContext =
242 bool bForm = pObjContext &&
243
244 pObjContext->HasNamespace(XML_NAMESPACE_FORM );
245 pMutableAttrList->SetValueByIndex( i,
246 GetTransformer().GetEventName( rAttrValue,
247 bForm ) );
248 }
249 break;
251 {
252 OUString aAttrValue( rAttrValue );
253 sal_uInt16 nValPrefix =
254 static_cast<sal_uInt16>((*aIter).second.m_nParam1);
256 aAttrValue, nValPrefix ) )
257 pMutableAttrList->SetValueByIndex( i, aAttrValue );
258 }
259 break;
261 {
262 OUString aName, aLocation;
263 bool bNeedsTransform =
264 ParseURL( rAttrValue, &aName, &aLocation );
265
266 if ( bNeedsTransform )
267 {
268 pMutableAttrList->SetValueByIndex( i, aName );
269
270 sal_Int16 idx = pMutableAttrList->GetIndexByName(
271 GetTransformer().GetNamespaceMap().GetQNameByKey(
274
275 if (idx != -1)
276 pMutableAttrList->SetValueByIndex(idx, "StarBasic");
277
278 OUString aLocQName(
279 GetTransformer().GetNamespaceMap().GetQNameByKey(
282
283 pMutableAttrList->AddAttribute( aLocQName, aLocation );
284 }
285 else
286 {
287 const OUString& rApp = GetXMLToken( XML_APPLICATION );
288 const OUString& rDoc = GetXMLToken( XML_DOCUMENT );
289 OUString aAttrValue;
290 if( rAttrValue.getLength() > rApp.getLength()+1 &&
291 o3tl::equalsIgnoreAsciiCase(rAttrValue.subView(0,rApp.getLength()), rApp) &&
292 ':' == rAttrValue[rApp.getLength()] )
293 {
294 aLocation = rApp;
295 aAttrValue = rAttrValue.copy( rApp.getLength()+1 );
296 }
297 else if( rAttrValue.getLength() > rDoc.getLength()+1 &&
298 o3tl::equalsIgnoreAsciiCase(rAttrValue.subView(0,rDoc.getLength()), rDoc) &&
299 ':' == rAttrValue[rDoc.getLength()] )
300 {
301 aLocation= rDoc;
302 aAttrValue = rAttrValue.copy( rDoc.getLength()+1 );
303 }
304 if( !aAttrValue.isEmpty() )
305 pMutableAttrList->SetValueByIndex( i,
306 aAttrValue );
307 if( !aLocation.isEmpty() )
308 {
309 OUString aAttrQName( GetTransformer().GetNamespaceMap().
310 GetQNameByKey( XML_NAMESPACE_SCRIPT,
312 pMutableAttrList->AddAttribute( aAttrQName, aLocation );
313 // draw bug
314 aAttrQName = GetTransformer().GetNamespaceMap().
315 GetQNameByKey( XML_NAMESPACE_SCRIPT,
317 pMutableAttrList->AddAttribute( aAttrQName, aLocation );
318 }
319 }
320 }
321 break;
323 break;
324 default:
325 SAL_WARN( "xmloff.transform", "unknown action" );
326 break;
327 }
328 }
329 }
330
332}
333
334/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@ OASIS_EVENT_ACTIONS
@ XML_ATACTION_EVENT_NAME
@ XML_ATACTION_HREF
@ XML_ATACTION_REMOVE_NAMESPACE_PREFIX
@ XML_ATACTION_COPY
@ XML_ATACTION_MACRO_NAME
XMLTransformerEventMapEntry const aFormTransformerEventMap[]
Definition: EventMap.cxx:95
XMLTransformerEventMapEntry const aTransformerEventMap[]
Definition: EventMap.cxx:24
static bool ParseURL(const OUString &rAttrValue, OUString *pName, OUString *pLocation)
const char * pName
sal_uInt16 GetKeyByAttrName(const OUString &rAttrName, OUString *pPrefix, OUString *pLocalName, OUString *pNamespace) const
static OUString GetEventName(sal_uInt16 nPrefix, const OUString &rName, XMLTransformerOASISEventMap_Impl &rMap, XMLTransformerOASISEventMap_Impl *pMap2)
static XMLTransformerOASISEventMap_Impl * CreateEventMap()
virtual ~XMLEventOASISTransformerContext() override
static XMLTransformerOASISEventMap_Impl * CreateFormEventMap()
static void FlushEventMap(XMLTransformerOASISEventMap_Impl *p)
XMLEventOASISTransformerContext(XMLTransformerBase &rTransformer, const OUString &rQName)
virtual void StartElement(const css::uno::Reference< css::xml::sax::XAttributeList > &xAttrList) override
virtual void StartElement(const css::uno::Reference< css::xml::sax::XAttributeList > &xAttrList) override
virtual XMLTransformerActions * GetUserDefinedActions(sal_uInt16 n)
SvXMLNamespaceMap & GetNamespaceMap()
bool RemoveNamespacePrefix(OUString &rName, sal_uInt16 nPrefixOnly=0xffffU) const
const XMLTransformerContext * GetAncestorContext(sal_uInt32 i) const
bool HasNamespace(sal_uInt16 nPrefix) const
XMLTransformerBase & GetTransformer()
XMLTransformerOASISEventMap_Impl(XMLTransformerEventMapEntry const *pInit)
Reference< XSingleServiceFactory > xFactory
const sal_uInt16 idx[]
OUString aName
void * p
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
constexpr OUStringLiteral aData
OSQLColumns::const_iterator find(const OSQLColumns::const_iterator &first, const OSQLColumns::const_iterator &last, std::u16string_view _rVal, const ::comphelper::UStringMixEqual &_rCase)
int i
bool equalsIgnoreAsciiCase(std::u16string_view s1, std::u16string_view s2)
end
Handling of tokens in XML:
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
return the OUString representation for eToken
Definition: xmltoken.cxx:3541
sal_uInt16 const m_nOASISPrefix
Definition: EventMap.hxx:26
constexpr sal_uInt16 XML_NAMESPACE_FORM
constexpr sal_uInt16 XML_NAMESPACE_SCRIPT