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 
20 #include "EventOASISTContext.hxx"
21 #include "EventMap.hxx"
22 #include "MutableAttrList.hxx"
23 #include <xmloff/xmlnmspe.hxx>
24 #include "ActionMapTypesOASIS.hxx"
26 #include "TransformerActions.hxx"
27 #include "TransformerBase.hxx"
28 #include <osl/diagnose.h>
29 #include <sal/log.hxx>
30 
31 // Used to parse Scripting Framework URLs
32 #include <com/sun/star/uri/UriReferenceFactory.hpp>
33 #include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
35 
36 #include <unordered_map>
37 
38 using namespace ::com::sun::star::uno;
39 using namespace ::com::sun::star::xml::sax;
40 using namespace ::xmloff::token;
41 
43  public std::unordered_map< NameKey_Impl, OUString,
44  NameHash_Impl, NameHash_Impl >
45 {
46 public:
48 };
49 
51 {
52  if( pInit )
53  {
54  XMLTransformerOASISEventMap_Impl::key_type aKey;
55  XMLTransformerOASISEventMap_Impl::mapped_type aData;
56  while( pInit->m_pOASISName )
57  {
58  aKey.m_nPrefix = pInit->m_nOASISPrefix;
59  aKey.m_aLocalName = OUString::createFromAscii(pInit->m_pOASISName);
60 
61  OSL_ENSURE( find( aKey ) == end(), "duplicate event map entry" );
62 
63  aData = OUString::createFromAscii(pInit->m_pOOoName);
64 
65  XMLTransformerOASISEventMap_Impl::value_type aVal( aKey, aData );
66 
67  insert( aVal );
68  ++pInit;
69  }
70  }
71 }
72 
74  XMLTransformerBase& rImp,
75  const OUString& rQName ) :
76  XMLRenameElemTransformerContext( rImp, rQName,
77  rImp.GetNamespaceMap().GetKeyByAttrName( rQName ), XML_EVENT )
78 {
79 }
80 
82 {
83 }
84 
87 {
89 }
90 
93 {
95 }
96 
99 {
100  delete p;
101 }
102 
104  sal_uInt16 nPrefix,
105  const OUString& rName,
108 {
109  XMLTransformerOASISEventMap_Impl::key_type aKey( nPrefix, rName );
110  if( pMap2 )
111  {
112  XMLTransformerOASISEventMap_Impl::const_iterator aIter =
113  pMap2->find( aKey );
114  if( aIter != pMap2->end() )
115  return (*aIter).second;
116  }
117 
118  XMLTransformerOASISEventMap_Impl::const_iterator aIter = rMap.find( aKey );
119  if( aIter == rMap.end() )
120  return rName;
121  else
122  return (*aIter).second;
123 }
124 
125 static bool ParseURL(
126  const OUString& rAttrValue,
127  OUString* pName, OUString* pLocation )
128 {
129  Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
130 
131  Reference< css::uri::XUriReferenceFactory > xFactory = css::uri::UriReferenceFactory::create(xContext);
132 
133  Reference< css::uri::XVndSunStarScriptUrl > xUrl ( xFactory->parse( rAttrValue ), UNO_QUERY );
134 
135  if ( xUrl.is() )
136  {
137  const OUString& aLanguageKey = GetXMLToken( XML_LANGUAGE );
138  if ( xUrl.is() && xUrl->hasParameter( aLanguageKey ) )
139  {
140  OUString aLanguage = xUrl->getParameter( aLanguageKey );
141 
142  if ( aLanguage.equalsIgnoreAsciiCase("basic") )
143  {
144  *pName = xUrl->getName();
145 
146  OUString tmp =
147  xUrl->getParameter( GetXMLToken( XML_LOCATION ) );
148 
149  const OUString& doc = GetXMLToken( XML_DOCUMENT );
150 
151  if ( tmp.equalsIgnoreAsciiCase( doc ) )
152  {
153  *pLocation = doc;
154  }
155  else
156  {
157  *pLocation = GetXMLToken( XML_APPLICATION );
158  }
159  return true;
160  }
161  }
162  }
163  return false;
164 }
165 
167  const Reference< XAttributeList >& rAttrList )
168 {
169  SAL_INFO("xmloff.transform", "XMLEventOASISTransformerContext::StartElement");
170 
171  XMLTransformerActions *pActions =
173  SAL_WARN_IF( pActions == nullptr, "xmloff.transform", "got no actions" );
174 
175  Reference< XAttributeList > xAttrList( rAttrList );
176  XMLMutableAttributeList *pMutableAttrList = nullptr;
177  sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
178  for( sal_Int16 i=0; i < nAttrCount; i++ )
179  {
180  const OUString& rAttrName = xAttrList->getNameByIndex( i );
181  OUString aLocalName;
182  sal_uInt16 nPrefix =
184  &aLocalName );
185  XMLTransformerActions::key_type aKey( nPrefix, aLocalName );
186  XMLTransformerActions::const_iterator aIter =
187  pActions->find( aKey );
188  if( aIter != pActions->end() )
189  {
190  if( !pMutableAttrList )
191  {
192  pMutableAttrList =
193  new XMLMutableAttributeList( xAttrList );
194  xAttrList = pMutableAttrList;
195  }
196  const OUString& rAttrValue = xAttrList->getValueByIndex( i );
197  switch( (*aIter).second.m_nActionType )
198  {
199  case XML_ATACTION_HREF:
200  {
201  OUString aName, aLocation;
202 
203  bool bNeedsTransform =
204  ParseURL( rAttrValue, &aName, &aLocation );
205 
206  if ( bNeedsTransform )
207  {
208  pMutableAttrList->RemoveAttributeByIndex( i );
209 
210  OUString aAttrQName(
211  GetTransformer().GetNamespaceMap().GetQNameByKey(
214 
215  pMutableAttrList->AddAttribute( aAttrQName, aName );
216 
217  sal_Int16 idx = pMutableAttrList->GetIndexByName(
218  GetTransformer().GetNamespaceMap().GetQNameByKey(
220  GetXMLToken( XML_LANGUAGE ) ) );
221 
222  pMutableAttrList->SetValueByIndex( idx,
223  "StarBasic" );
224 
225  OUString aLocQName(
226  GetTransformer().GetNamespaceMap().GetQNameByKey(
228  GetXMLToken( XML_LOCATION ) ) );
229 
230  pMutableAttrList->AddAttribute( aLocQName, aLocation );
231  }
232  }
233  break;
235  {
236  // Check if the event belongs to a form or control by
237  // checking the 2nd ancestor element, f.i.:
238  // <form:button><form:event-listeners><form:event-listener>
239  const XMLTransformerContext *pObjContext =
241  bool bForm = pObjContext &&
242 
243  pObjContext->HasNamespace(XML_NAMESPACE_FORM );
244  pMutableAttrList->SetValueByIndex( i,
245  GetTransformer().GetEventName( rAttrValue,
246  bForm ) );
247  }
248  break;
250  {
251  OUString aAttrValue( rAttrValue );
252  sal_uInt16 nValPrefix =
253  static_cast<sal_uInt16>((*aIter).second.m_nParam1);
255  aAttrValue, nValPrefix ) )
256  pMutableAttrList->SetValueByIndex( i, aAttrValue );
257  }
258  break;
260  {
261  OUString aName, aLocation;
262  bool bNeedsTransform =
263  ParseURL( rAttrValue, &aName, &aLocation );
264 
265  if ( bNeedsTransform )
266  {
267  pMutableAttrList->SetValueByIndex( i, aName );
268 
269  sal_Int16 idx = pMutableAttrList->GetIndexByName(
270  GetTransformer().GetNamespaceMap().GetQNameByKey(
272  GetXMLToken( XML_LANGUAGE ) ) );
273 
274  pMutableAttrList->SetValueByIndex( idx,
275  "StarBasic" );
276 
277  OUString aLocQName(
278  GetTransformer().GetNamespaceMap().GetQNameByKey(
280  GetXMLToken( XML_LOCATION ) ) );
281 
282  pMutableAttrList->AddAttribute( aLocQName, aLocation );
283  }
284  else
285  {
286  const OUString& rApp = GetXMLToken( XML_APPLICATION );
287  const OUString& rDoc = GetXMLToken( XML_DOCUMENT );
288  OUString aAttrValue;
289  if( rAttrValue.getLength() > rApp.getLength()+1 &&
290  rAttrValue.copy(0,rApp.getLength()).
291  equalsIgnoreAsciiCase( 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  rAttrValue.copy(0,rDoc.getLength()).
299  equalsIgnoreAsciiCase( rDoc ) &&
300  ':' == rAttrValue[rDoc.getLength()] )
301  {
302  aLocation= rDoc;
303  aAttrValue = rAttrValue.copy( rDoc.getLength()+1 );
304  }
305  if( !aAttrValue.isEmpty() )
306  pMutableAttrList->SetValueByIndex( i,
307  aAttrValue );
308  if( !aLocation.isEmpty() )
309  {
310  OUString aAttrQName( GetTransformer().GetNamespaceMap().
311  GetQNameByKey( XML_NAMESPACE_SCRIPT,
313  pMutableAttrList->AddAttribute( aAttrQName, aLocation );
314  // draw bug
315  aAttrQName = GetTransformer().GetNamespaceMap().
316  GetQNameByKey( XML_NAMESPACE_SCRIPT,
318  pMutableAttrList->AddAttribute( aAttrQName, aLocation );
319  }
320  }
321  }
322  break;
323  case XML_ATACTION_COPY:
324  break;
325  default:
326  SAL_WARN( "xmloff.transform", "unknown action" );
327  break;
328  }
329  }
330  }
331 
333 }
334 
335 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static XMLTransformerOASISEventMap_Impl * CreateFormEventMap()
const char aData[]
static bool ParseURL(const OUString &rAttrValue, OUString *pName, OUString *pLocation)
XMLTransformerEventMapEntry const aFormTransformerEventMap[]
Definition: EventMap.cxx:95
virtual ~XMLEventOASISTransformerContext() override
sal_uInt16 GetKeyByAttrName(const OUString &rAttrName, OUString *pPrefix, OUString *pLocalName, OUString *pNamespace) const
Definition: nmspmap.cxx:437
sal_Int16 GetIndexByName(const OUString &rName) const
XMLEventOASISTransformerContext(XMLTransformerBase &rTransformer, const OUString &rQName)
SvXMLNamespaceMap & GetNamespaceMap()
virtual sal_Int16 SAL_CALL getLength() override
bool RemoveNamespacePrefix(OUString &rName, sal_uInt16 nPrefixOnly=0xffffU) const
sal_uInt16 char * pName
int i
OSQLColumns::const_iterator find(const OSQLColumns::const_iterator &first, const OSQLColumns::const_iterator &last, const OUString &_rVal, const ::comphelper::UStringMixEqual &_rCase)
virtual void StartElement(const css::uno::Reference< css::xml::sax::XAttributeList > &xAttrList) override
void SetValueByIndex(sal_Int16 i, const OUString &rValue)
bool HasNamespace(sal_uInt16 nPrefix) const
void RemoveAttributeByIndex(sal_Int16 i)
const XMLTransformerContext * GetAncestorContext(sal_uInt32 i) const
void AddAttribute(const OUString &sName, const OUString &sValue)
XMLTransformerEventMapEntry const aTransformerEventMap[]
Definition: EventMap.cxx:24
constexpr sal_uInt16 XML_NAMESPACE_FORM
Definition: xmlnmspe.hxx:44
enumrange< T >::Iterator end(enumrange< T >)
virtual void StartElement(const css::uno::Reference< css::xml::sax::XAttributeList > &xAttrList) override
virtual XMLTransformerActions * GetUserDefinedActions(sal_uInt16 n)
XMLTransformerBase & GetTransformer()
#define SAL_WARN_IF(condition, area, stream)
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
return the OUString representation for eToken
Definition: xmltoken.cxx:3366
Handling of tokens in XML:
#define SAL_INFO(area, stream)
XMLTransformerOASISEventMap_Impl(XMLTransformerEventMapEntry const *pInit)
OUString aName
static OUString GetEventName(sal_uInt16 nPrefix, const OUString &rName, XMLTransformerOASISEventMap_Impl &rMap, XMLTransformerOASISEventMap_Impl *pMap2)
#define SAL_WARN(area, stream)
Reference< XSingleServiceFactory > xFactory
static void FlushEventMap(XMLTransformerOASISEventMap_Impl *p)
sal_uInt16 const m_nOASISPrefix
Definition: EventMap.hxx:27
virtual OUString SAL_CALL getValueByIndex(sal_Int16 i) override
constexpr sal_uInt16 XML_NAMESPACE_SCRIPT
Definition: xmlnmspe.hxx:45
static XMLTransformerOASISEventMap_Impl * CreateEventMap()