merge the formfield patch from ooo-build
[ooovba.git] / framework / source / xml / eventsdocumenthandler.cxx
blobf160ffe895e006bd949ba89ed461fcbb9be894c6
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: eventsdocumenthandler.cxx,v $
10 * $Revision: 1.11 $
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_framework.hxx"
34 #include <stdio.h>
36 //_________________________________________________________________________________________________________________
37 // my own includes
38 //_________________________________________________________________________________________________________________
40 #include <threadhelp/resetableguard.hxx>
41 #include <xml/eventsdocumenthandler.hxx>
42 #include <macros/debug.hxx>
44 //_________________________________________________________________________________________________________________
45 // interface includes
46 //_________________________________________________________________________________________________________________
48 #ifndef __COM_SUN_STAR_XML_SAX_XEXTENDEDDOCUMENTHANDLER_HPP_
49 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
50 #endif
52 //_________________________________________________________________________________________________________________
53 // other includes
54 //_________________________________________________________________________________________________________________
56 #include <sal/config.h>
57 #include <vcl/svapp.hxx>
58 #include <vcl/toolbox.hxx>
60 #include <comphelper/attributelist.hxx>
62 //_________________________________________________________________________________________________________________
63 // namespace
64 //_________________________________________________________________________________________________________________
66 using namespace ::com::sun::star::uno;
67 using namespace ::com::sun::star::beans;
68 using namespace ::com::sun::star::xml::sax;
71 #define XMLNS_EVENT "http://openoffice.org/2001/event"
72 #define XMLNS_XLINK "http://www.w3.org/1999/xlink"
73 #define XMLNS_EVENT_PREFIX "event:"
74 #define XMLNS_XLINK_PREFIX "xlink:"
76 #define ATTRIBUTE_XMLNS_EVENT "xmlns:event"
77 #define ATTRIBUTE_XMLNS_XLINK "xmlns:xlink"
79 #define XMLNS_FILTER_SEPARATOR "^"
81 #define ELEMENT_EVENTS "events"
82 #define ELEMENT_EVENT "event"
84 #define ATTRIBUTE_LANGUAGE "language"
85 #define ATTRIBUTE_LIBRARY "library"
86 #define ATTRIBUTE_NAME "name"
87 #define ATTRIBUTE_HREF "href"
88 #define ATTRIBUTE_TYPE "type"
89 #define ATTRIBUTE_MACRONAME "macro-name"
91 #define ELEMENT_NS_EVENTS "event:events"
92 #define ELEMENT_NS_EVENT "event:event"
94 #define ATTRIBUTE_TYPE_CDATA "CDATA"
96 #define EVENTS_DOCTYPE "<!DOCTYPE event:events PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"event.dtd\">"
98 // Property names for events
99 #define PROP_EVENT_TYPE "EventType"
100 #define PROP_LIBRARY "Library"
101 #define PROP_SCRIPT "Script"
102 #define PROP_MACRO_NAME "MacroName"
103 #define STAR_BASIC "StarBasic"
104 #define JAVA_SCRIPT "JavaScript"
107 namespace framework
110 struct EventEntryProperty
112 OReadEventsDocumentHandler::Event_XML_Namespace nNamespace;
113 char aEntryName[20];
116 static EventEntryProperty EventEntries[OReadEventsDocumentHandler::EV_XML_ENTRY_COUNT] =
118 { OReadEventsDocumentHandler::EV_NS_EVENT, ELEMENT_EVENTS },
119 { OReadEventsDocumentHandler::EV_NS_EVENT, ELEMENT_EVENT },
120 { OReadEventsDocumentHandler::EV_NS_EVENT, ATTRIBUTE_LANGUAGE },
121 { OReadEventsDocumentHandler::EV_NS_EVENT, ATTRIBUTE_NAME },
122 { OReadEventsDocumentHandler::EV_NS_XLINK, ATTRIBUTE_HREF },
123 { OReadEventsDocumentHandler::EV_NS_XLINK, ATTRIBUTE_TYPE },
124 { OReadEventsDocumentHandler::EV_NS_EVENT, ATTRIBUTE_MACRONAME },
125 { OReadEventsDocumentHandler::EV_NS_EVENT, ATTRIBUTE_LIBRARY }
129 OReadEventsDocumentHandler::OReadEventsDocumentHandler( EventsConfig& aItems ) :
130 ThreadHelpBase( &Application::GetSolarMutex() ),
131 m_aEventItems( aItems )
133 ::rtl::OUString aNamespaceEvent( RTL_CONSTASCII_USTRINGPARAM( XMLNS_EVENT ));
134 ::rtl::OUString aNamespaceXLink( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK ));
135 ::rtl::OUString aSeparator( RTL_CONSTASCII_USTRINGPARAM( XMLNS_FILTER_SEPARATOR ));
137 // create hash map
138 for ( int i = 0; i < (int)EV_XML_ENTRY_COUNT; i++ )
140 if ( EventEntries[i].nNamespace == EV_NS_EVENT )
142 ::rtl::OUString temp( aNamespaceEvent );
143 temp += aSeparator;
144 temp += ::rtl::OUString::createFromAscii( EventEntries[i].aEntryName );
145 m_aEventsMap.insert( EventsHashMap::value_type( temp, (Events_XML_Entry)i ) );
147 else
149 ::rtl::OUString temp( aNamespaceXLink );
150 temp += aSeparator;
151 temp += ::rtl::OUString::createFromAscii( EventEntries[i].aEntryName );
152 m_aEventsMap.insert( EventsHashMap::value_type( temp, (Events_XML_Entry)i ) );
156 m_bEventsStartFound = sal_False;
157 m_bEventsEndFound = sal_False;
158 m_bEventStartFound = sal_False;
161 OReadEventsDocumentHandler::~OReadEventsDocumentHandler()
165 // XDocumentHandler
166 void SAL_CALL OReadEventsDocumentHandler::startDocument(void)
167 throw ( SAXException, RuntimeException )
171 void SAL_CALL OReadEventsDocumentHandler::endDocument(void)
172 throw( SAXException, RuntimeException )
174 ResetableGuard aGuard( m_aLock );
176 if (( m_bEventsStartFound && !m_bEventsEndFound ) ||
177 ( !m_bEventsStartFound && m_bEventsEndFound ) )
179 ::rtl::OUString aErrorMessage = getErrorLineString();
180 aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "No matching start or end element 'event:events' found!" ));
181 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
185 void SAL_CALL OReadEventsDocumentHandler::startElement(
186 const ::rtl::OUString& aName, const Reference< XAttributeList > &xAttribs )
187 throw( SAXException, RuntimeException )
189 ResetableGuard aGuard( m_aLock );
191 EventsHashMap::const_iterator pEventEntry = m_aEventsMap.find( aName );
192 if ( pEventEntry != m_aEventsMap.end() )
194 switch ( pEventEntry->second )
196 case EV_ELEMENT_EVENTS:
198 if ( m_bEventsStartFound )
200 ::rtl::OUString aErrorMessage = getErrorLineString();
201 aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'event:events' cannot be embeded into 'event:events'!" ));
202 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
205 m_bEventsStartFound = sal_True;
207 break;
209 case EV_ELEMENT_EVENT:
211 if ( !m_bEventsStartFound )
213 ::rtl::OUString aErrorMessage = getErrorLineString();
214 aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'event:event' must be embeded into element 'event:events'!" ));
215 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
218 if ( m_bEventStartFound )
220 ::rtl::OUString aErrorMessage = getErrorLineString();
221 aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element event:event is not a container!" ));
222 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
225 ::rtl::OUString aLanguage;
226 ::rtl::OUString aURL;
227 ::rtl::OUString aMacroName;
228 ::rtl::OUString aLibrary;
229 ::rtl::OUString aEventName;
231 m_bEventStartFound = sal_True;
233 long nIndex = m_aEventItems.aEventNames.getLength();
234 long nPropCount = 2; // every event config entry needs at least 2 properties
235 Sequence< PropertyValue > aEventProperties( nPropCount );
237 m_aEventItems.aEventNames.realloc( nIndex + 1 );
239 for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ )
241 pEventEntry = m_aEventsMap.find( xAttribs->getNameByIndex( n ) );
242 if ( pEventEntry != m_aEventsMap.end() )
244 switch ( pEventEntry->second )
246 case EV_ATTRIBUTE_TYPE:
248 aLanguage = xAttribs->getValueByIndex( n );
250 break;
252 case EV_ATTRIBUTE_NAME:
254 aEventName = xAttribs->getValueByIndex( n );
256 break;
258 case XL_ATTRIBUTE_HREF:
260 aURL = xAttribs->getValueByIndex( n );
262 break;
264 case EV_ATTRIBUTE_MACRONAME:
266 aMacroName = xAttribs->getValueByIndex( n );
268 break;
270 case EV_ATTRIBUTE_LIBRARY:
272 aLibrary = xAttribs->getValueByIndex( n );
274 break;
276 default:
277 break; // nothing to do
280 } // for
282 ::rtl::OUString aRequiredAttributeName;
283 if ( aLanguage.getLength() == 0 )
284 aRequiredAttributeName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE ));
285 else if ( aEventName.getLength() == 0 )
286 aRequiredAttributeName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NAME ));
288 // check for missing attribute values
289 if ( aRequiredAttributeName.getLength() > 0 )
291 ::rtl::OUString aErrorMessage = getErrorLineString();
292 aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute "));
293 aErrorMessage += aRequiredAttributeName;
294 aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " must have a value!" ));
295 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
298 Any a;
300 // set properties
301 a <<= aLanguage;
302 aEventProperties[0].Value <<= a;
303 aEventProperties[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( PROP_EVENT_TYPE ));
305 a <<= aMacroName;
306 aEventProperties[1].Value <<= a;
307 aEventProperties[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( PROP_MACRO_NAME ));
309 if ( aLibrary.getLength() > 0 )
311 ++nPropCount;
312 aEventProperties.realloc( nPropCount );
313 a <<= aLibrary;
314 aEventProperties[nPropCount-1].Value <<= a;
315 aEventProperties[nPropCount-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( PROP_LIBRARY ));
318 if ( aURL.getLength() > 0 )
320 ++nPropCount;
321 aEventProperties.realloc( nPropCount );
322 a <<= aURL;
323 aEventProperties[nPropCount-1].Value <<= a;
324 aEventProperties[nPropCount-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( PROP_SCRIPT ));
327 // set event name
328 m_aEventItems.aEventNames[ nIndex ] = aEventName;
330 m_aEventItems.aEventsProperties.realloc( nIndex + 1 );
331 a <<= aEventProperties;
332 m_aEventItems.aEventsProperties[ nIndex ] = a;
334 break;
336 default:
337 break;
342 void SAL_CALL OReadEventsDocumentHandler::endElement(const ::rtl::OUString& aName)
343 throw( SAXException, RuntimeException )
345 ResetableGuard aGuard( m_aLock );
347 EventsHashMap::const_iterator pEventEntry = m_aEventsMap.find( aName );
348 if ( pEventEntry != m_aEventsMap.end() )
350 switch ( pEventEntry->second )
352 case EV_ELEMENT_EVENTS:
354 if ( !m_bEventsStartFound )
356 ::rtl::OUString aErrorMessage = getErrorLineString();
357 aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'event:events' found, but no start element" ));
358 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
361 m_bEventsStartFound = sal_False;
363 break;
365 case EV_ELEMENT_EVENT:
367 if ( !m_bEventStartFound )
369 ::rtl::OUString aErrorMessage = getErrorLineString();
370 aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'event:event' found, but no start element" ));
371 throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
374 m_bEventStartFound = sal_False;
376 break;
378 default:
379 break; // impossible case
384 void SAL_CALL OReadEventsDocumentHandler::characters(const ::rtl::OUString&)
385 throw( SAXException, RuntimeException )
389 void SAL_CALL OReadEventsDocumentHandler::ignorableWhitespace(const ::rtl::OUString&)
390 throw( SAXException, RuntimeException )
394 void SAL_CALL OReadEventsDocumentHandler::processingInstruction(
395 const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ )
396 throw( SAXException, RuntimeException )
400 void SAL_CALL OReadEventsDocumentHandler::setDocumentLocator(
401 const Reference< XLocator > &xLocator)
402 throw( SAXException, RuntimeException )
404 ResetableGuard aGuard( m_aLock );
406 m_xLocator = xLocator;
409 ::rtl::OUString OReadEventsDocumentHandler::getErrorLineString()
411 ResetableGuard aGuard( m_aLock );
413 char buffer[32];
415 if ( m_xLocator.is() )
417 snprintf( buffer, sizeof(buffer), "Line: %ld - ", static_cast<long>(m_xLocator->getLineNumber() ));
418 return ::rtl::OUString::createFromAscii( buffer );
420 else
421 return ::rtl::OUString();
425 //_________________________________________________________________________________________________________________
426 // OWriteEventsDocumentHandler
427 //_________________________________________________________________________________________________________________
429 OWriteEventsDocumentHandler::OWriteEventsDocumentHandler(
430 const EventsConfig& aItems,
431 Reference< XDocumentHandler > rWriteDocumentHandler ) :
432 ThreadHelpBase( &Application::GetSolarMutex() ),
433 m_aItems( aItems ),
434 m_xWriteDocumentHandler( rWriteDocumentHandler )
436 ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
437 m_xEmptyList = Reference< XAttributeList >( (XAttributeList *) pList, UNO_QUERY );
438 m_aAttributeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE_CDATA ));
439 m_aXMLXlinkNS = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK_PREFIX ));
440 m_aXMLEventNS = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_EVENT_PREFIX ));
443 OWriteEventsDocumentHandler::~OWriteEventsDocumentHandler()
447 void OWriteEventsDocumentHandler::WriteEventsDocument() throw
448 ( SAXException, RuntimeException )
450 ResetableGuard aGuard( m_aLock );
452 m_xWriteDocumentHandler->startDocument();
454 // write DOCTYPE line!
455 Reference< XExtendedDocumentHandler > xExtendedDocHandler( m_xWriteDocumentHandler, UNO_QUERY );
456 if ( xExtendedDocHandler.is() )
458 xExtendedDocHandler->unknown( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( EVENTS_DOCTYPE )) );
459 m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
462 ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
463 Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
465 pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_EVENT )),
466 m_aAttributeType,
467 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_EVENT )) );
468 pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_XLINK )),
469 m_aAttributeType,
470 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK )) );
472 m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EVENTS )), pList );
473 m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
475 Sequence< PropertyValue > aEventProperties;
477 for ( int i = 0; i < m_aItems.aEventNames.getLength(); i++ )
479 if ( m_aItems.aEventsProperties[i] >>= aEventProperties )
480 WriteEvent( m_aItems.aEventNames[i], aEventProperties );
483 m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
484 m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EVENTS )) );
486 m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
487 m_xWriteDocumentHandler->endDocument();
490 //_________________________________________________________________________________________________________________
491 // protected member functions
492 //_________________________________________________________________________________________________________________
494 void OWriteEventsDocumentHandler::WriteEvent( const ::rtl::OUString& aEventName, const Sequence< PropertyValue >& aPropertyValues ) throw
495 ( SAXException, RuntimeException )
497 if ( aPropertyValues.getLength() > 0 )
499 ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
500 Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
502 if ( m_aAttributeURL.getLength() == 0 )
504 m_aAttributeURL = m_aXMLXlinkNS;
505 m_aAttributeURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_HREF ));
506 m_aAttributeLinkType = m_aXMLXlinkNS;
507 m_aAttributeLinkType += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE ));
508 m_aAttributeLanguage = m_aXMLEventNS;
509 m_aAttributeLanguage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_LANGUAGE ));
510 m_aAttributeMacroName = m_aXMLEventNS;
511 m_aAttributeMacroName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MACRONAME ));
512 m_aAttributeLibrary = m_aXMLEventNS;
513 m_aAttributeLibrary += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_LIBRARY ));
514 m_aAttributeName = m_aXMLEventNS;
515 m_aAttributeName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NAME ));
518 pList->AddAttribute( m_aAttributeName, m_aAttributeType, aEventName );
520 sal_Bool bURLSet = sal_False;
521 ::rtl::OUString aValue;
522 ::rtl::OUString aName;
524 // save attributes
525 for ( int i = 0; i < aPropertyValues.getLength(); i++ )
527 aPropertyValues[i].Value >>= aValue;
528 if ( aPropertyValues[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( PROP_EVENT_TYPE )))
529 pList->AddAttribute( m_aAttributeLanguage, m_aAttributeType, aValue );
530 else if ( aPropertyValues[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( PROP_MACRO_NAME )) &&
531 aValue.getLength() > 0 )
532 pList->AddAttribute( m_aAttributeMacroName, m_aAttributeType, aValue );
533 else if ( aPropertyValues[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( PROP_LIBRARY )) &&
534 aValue.getLength() > 0 )
535 pList->AddAttribute( m_aAttributeLibrary, m_aAttributeType, aValue );
536 else if ( aPropertyValues[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( PROP_SCRIPT )))
538 pList->AddAttribute( m_aAttributeURL, m_aAttributeType, aValue );
539 bURLSet = sal_True;
543 if ( bURLSet )
544 pList->AddAttribute( m_aAttributeLinkType, m_aAttributeType, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "simple" )) );
546 m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EVENT )), xList );
547 m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
549 m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EVENT )) );
550 m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
554 } // namespace framework