1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_xmloff.hxx" 30 #include "EventOOoTContext.hxx" 31 #include "EventMap.hxx" 32 #include "MutableAttrList.hxx" 33 #include "xmloff/xmlnmspe.hxx" 34 #ifndef _XMLOFF_ACTIONMAPTYPESOOo_HXX 35 #include "ActionMapTypesOOo.hxx" 36 #endif 37 #include "AttrTransformerAction.hxx" 38 #include "TransformerActions.hxx" 39 #ifndef _XMLOFF_TRANSFORMERBASE_HXX 40 #include "TransformerBase.hxx" 41 #endif 42 #include <comphelper/stl_types.hxx> 43 #include <rtl/ustrbuf.hxx> 44 45 #include <hash_map> 46 47 using ::rtl::OUString; 48 using ::rtl::OUStringBuffer; 49 using namespace ::com::sun::star::uno; 50 using namespace ::com::sun::star::xml::sax; 51 using namespace ::xmloff::token; 52 53 class XMLTransformerOOoEventMap_Impl: 54 public ::std::hash_map< ::rtl::OUString, NameKey_Impl, 55 ::rtl::OUStringHash, ::comphelper::UStringEqual > 56 { 57 public: 58 59 void AddMap( XMLTransformerEventMapEntry *pInit ); 60 61 XMLTransformerOOoEventMap_Impl( XMLTransformerEventMapEntry *pInit, 62 XMLTransformerEventMapEntry *pInit2 ); 63 ~XMLTransformerOOoEventMap_Impl(); 64 }; 65 66 void XMLTransformerOOoEventMap_Impl::AddMap( XMLTransformerEventMapEntry *pInit ) 67 { 68 XMLTransformerOOoEventMap_Impl::key_type aKey; 69 XMLTransformerOOoEventMap_Impl::data_type aData; 70 while( pInit->m_pOOoName ) 71 { 72 aKey = OUString::createFromAscii(pInit->m_pOOoName); 73 74 OSL_ENSURE( find( aKey ) == end(), "duplicate event map entry" ); 75 76 aData.m_nPrefix = pInit->m_nOASISPrefix; 77 aData.m_aLocalName = OUString::createFromAscii(pInit->m_pOASISName); 78 79 XMLTransformerOOoEventMap_Impl::value_type aVal( aKey, aData ); 80 81 if( !insert( aVal ).second ) 82 { 83 OSL_ENSURE( false, "duplicate OOo event name extry" ); 84 } 85 86 ++pInit; 87 } 88 } 89 90 XMLTransformerOOoEventMap_Impl::XMLTransformerOOoEventMap_Impl( 91 XMLTransformerEventMapEntry *pInit, 92 XMLTransformerEventMapEntry *pInit2 ) 93 { 94 if( pInit ) 95 AddMap( pInit ); 96 if( pInit ) 97 AddMap( pInit2 ); 98 } 99 100 XMLTransformerOOoEventMap_Impl::~XMLTransformerOOoEventMap_Impl() 101 { 102 } 103 104 // ----------------------------------------------------------------------------- 105 106 TYPEINIT1( XMLEventOOoTransformerContext, XMLPersElemContentTContext ); 107 108 XMLEventOOoTransformerContext::XMLEventOOoTransformerContext( 109 XMLTransformerBase& rImp, 110 const OUString& rQName, 111 sal_Bool bPersistent ) : 112 XMLPersElemContentTContext( rImp, rQName, 113 rImp.GetNamespaceMap().GetKeyByAttrName( rQName ), XML_EVENT_LISTENER ), 114 m_bPersistent( bPersistent ) 115 { 116 } 117 118 XMLEventOOoTransformerContext::~XMLEventOOoTransformerContext() 119 { 120 } 121 122 XMLTransformerOOoEventMap_Impl 123 *XMLEventOOoTransformerContext::CreateEventMap() 124 { 125 return new XMLTransformerOOoEventMap_Impl( aTransformerEventMap, 126 aFormTransformerEventMap ); 127 } 128 129 void XMLEventOOoTransformerContext::FlushEventMap( 130 XMLTransformerOOoEventMap_Impl *p ) 131 { 132 delete p; 133 } 134 135 sal_uInt16 XMLEventOOoTransformerContext::GetEventName( 136 const OUString& rName, 137 OUString& rNewName, 138 XMLTransformerOOoEventMap_Impl& rMap ) 139 { 140 XMLTransformerOOoEventMap_Impl::key_type aKey( rName ); 141 XMLTransformerOOoEventMap_Impl::const_iterator aIter = rMap.find( aKey ); 142 if( aIter == rMap.end() ) 143 { 144 rNewName = rName; 145 return XML_NAMESPACE_UNKNOWN; 146 } 147 else 148 { 149 rNewName = (*aIter).second.m_aLocalName; 150 return (*aIter).second.m_nPrefix; 151 } 152 } 153 154 155 void XMLEventOOoTransformerContext::StartElement( 156 const Reference< XAttributeList >& rAttrList ) 157 { 158 XMLTransformerActions *pActions = 159 GetTransformer().GetUserDefinedActions( OOO_EVENT_ACTIONS ); 160 OSL_ENSURE( pActions, "go no actions" ); 161 162 OUString aLocation, aMacroName; 163 sal_Int16 nMacroName = -1; 164 Reference< XAttributeList > xAttrList( rAttrList ); 165 XMLMutableAttributeList *pMutableAttrList = 0; 166 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; 167 for( sal_Int16 i=0; i < nAttrCount; i++ ) 168 { 169 const OUString& rAttrName = xAttrList->getNameByIndex( i ); 170 OUString aLocalName; 171 sal_uInt16 nPrefix = 172 GetTransformer().GetNamespaceMap().GetKeyByAttrName( rAttrName, 173 &aLocalName ); 174 XMLTransformerActions::key_type aKey( nPrefix, aLocalName ); 175 XMLTransformerActions::const_iterator aIter = 176 pActions->find( aKey ); 177 if( !(aIter == pActions->end() ) ) 178 { 179 if( !pMutableAttrList ) 180 { 181 pMutableAttrList = 182 new XMLMutableAttributeList( xAttrList ); 183 xAttrList = pMutableAttrList; 184 } 185 const OUString& rAttrValue = xAttrList->getValueByIndex( i ); 186 switch( (*aIter).second.m_nActionType ) 187 { 188 case XML_ATACTION_HREF: 189 // TODO 190 break; 191 case XML_ATACTION_EVENT_NAME: 192 pMutableAttrList->SetValueByIndex( i, 193 GetTransformer().GetEventName( rAttrValue ) ); 194 break; 195 case XML_ATACTION_ADD_NAMESPACE_PREFIX: 196 { 197 OUString aAttrValue( rAttrValue ); 198 sal_uInt16 nValPrefix = 199 static_cast<sal_uInt16>((*aIter).second.m_nParam1); 200 if( GetTransformer().AddNamespacePrefix( aAttrValue, 201 nValPrefix ) ) 202 pMutableAttrList->SetValueByIndex( i, aAttrValue ); 203 } 204 break; 205 case XML_ATACTION_MACRO_LOCATION: 206 aLocation = rAttrValue; 207 pMutableAttrList->RemoveAttributeByIndex( i ); 208 --i; 209 --nAttrCount; 210 break; 211 case XML_ATACTION_MACRO_NAME: 212 aMacroName = rAttrValue; 213 nMacroName = i; 214 break; 215 case XML_ATACTION_COPY: 216 break; 217 default: 218 OSL_ENSURE( !this, "unknown action" ); 219 break; 220 } 221 } 222 } 223 224 if( nMacroName != -1 && aLocation.getLength() > 0 ) 225 { 226 if( !IsXMLToken( aLocation, XML_APPLICATION ) ) 227 aLocation = GetXMLToken( XML_DOCUMENT ); 228 OUStringBuffer sTmp( aLocation.getLength() + aMacroName.getLength() + 1 ); 229 sTmp = aLocation; 230 sTmp.append( sal_Unicode( ':' ) ); 231 sTmp.append( aMacroName ); 232 pMutableAttrList->SetValueByIndex( nMacroName, 233 sTmp.makeStringAndClear() ); 234 } 235 236 if( m_bPersistent ) 237 XMLPersElemContentTContext::StartElement( xAttrList ); 238 else 239 GetTransformer().GetDocHandler()->startElement( GetExportQName(), 240 xAttrList ); 241 } 242 243 void XMLEventOOoTransformerContext::EndElement() 244 { 245 if( m_bPersistent ) 246 XMLPersElemContentTContext::EndElement(); 247 else 248 GetTransformer().GetDocHandler()->endElement( GetExportQName() ); 249 } 250 251 XMLTransformerContext * XMLEventOOoTransformerContext::CreateChildContext( 252 sal_uInt16 nPrefix, 253 const OUString& rLocalName, 254 const OUString& rQName, 255 const Reference< XAttributeList >& xAttrList ) 256 { 257 if( m_bPersistent ) 258 return XMLPersElemContentTContext::CreateChildContext(nPrefix, rLocalName, rQName, xAttrList); 259 else 260 return XMLTransformerContext::CreateChildContext(nPrefix, rLocalName, rQName, xAttrList); 261 } 262 263 sal_Bool XMLEventOOoTransformerContext::IsPersistent() const 264 { 265 return m_bPersistent; 266 } 267