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
XMLTransformerOASISEventMap_Impl(XMLTransformerEventMapEntry * pInit)61 XMLTransformerOASISEventMap_Impl::XMLTransformerOASISEventMap_Impl( XMLTransformerEventMapEntry *pInit )
62 {
63 if( pInit )
64 {
65 XMLTransformerOASISEventMap_Impl::key_type aKey;
66 XMLTransformerOASISEventMap_Impl::mapped_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
~XMLTransformerOASISEventMap_Impl()84 XMLTransformerOASISEventMap_Impl::~XMLTransformerOASISEventMap_Impl()
85 {
86 }
87
88 // -----------------------------------------------------------------------------
89
90 TYPEINIT1( XMLEventOASISTransformerContext, XMLRenameElemTransformerContext);
91
XMLEventOASISTransformerContext(XMLTransformerBase & rImp,const OUString & rQName)92 XMLEventOASISTransformerContext::XMLEventOASISTransformerContext(
93 XMLTransformerBase& rImp,
94 const OUString& rQName ) :
95 XMLRenameElemTransformerContext( rImp, rQName,
96 rImp.GetNamespaceMap().GetKeyByAttrName( rQName ), XML_EVENT )
97 {
98 }
99
~XMLEventOASISTransformerContext()100 XMLEventOASISTransformerContext::~XMLEventOASISTransformerContext()
101 {
102 }
103
104 XMLTransformerOASISEventMap_Impl
CreateEventMap()105 *XMLEventOASISTransformerContext::CreateEventMap()
106 {
107 return new XMLTransformerOASISEventMap_Impl( aTransformerEventMap );
108 }
109
110 XMLTransformerOASISEventMap_Impl
CreateFormEventMap()111 *XMLEventOASISTransformerContext::CreateFormEventMap()
112 {
113 return new XMLTransformerOASISEventMap_Impl( aFormTransformerEventMap );
114 }
115
FlushEventMap(XMLTransformerOASISEventMap_Impl * p)116 void XMLEventOASISTransformerContext::FlushEventMap(
117 XMLTransformerOASISEventMap_Impl *p )
118 {
119 delete p;
120 }
121
GetEventName(sal_uInt16 nPrefix,const OUString & rName,XMLTransformerOASISEventMap_Impl & rMap,XMLTransformerOASISEventMap_Impl * pMap2)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
ParseURLAsString(const OUString & rAttrValue,OUString * pName,OUString * pLocation)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
ParseURL(const OUString & rAttrValue,OUString * pName,OUString * pLocation)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
StartElement(const Reference<XAttributeList> & rAttrList)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( sal_False, "unknown action" );
410 break;
411 }
412 }
413 }
414
415 XMLRenameElemTransformerContext::StartElement( xAttrList );
416 }
417