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 "MergeElemTContext.hxx" 31 #include "MutableAttrList.hxx" 32 #ifndef _XMLOFF_TRANSFORMERBASE_HXX 33 #include "TransformerBase.hxx" 34 #endif 35 #include "TransformerActions.hxx" 36 #include "AttrTransformerAction.hxx" 37 #include "ElemTransformerAction.hxx" 38 #include "IgnoreTContext.hxx" 39 #include "xmloff/xmlnmspe.hxx" 40 41 using ::rtl::OUString; 42 using namespace ::com::sun::star::uno; 43 using namespace ::com::sun::star::xml::sax; 44 using namespace ::xmloff::token; 45 46 class XMLParagraphTransformerContext : public XMLTransformerContext 47 { 48 public: 49 TYPEINFO(); 50 51 XMLParagraphTransformerContext( XMLTransformerBase& rTransformer, 52 const ::rtl::OUString& rQName ); 53 54 virtual ~XMLParagraphTransformerContext(); 55 56 // Create a childs element context. By default, the import's 57 // CreateContext method is called to create a new default context. 58 virtual XMLTransformerContext *CreateChildContext( sal_uInt16 nPrefix, 59 const ::rtl::OUString& rLocalName, 60 const ::rtl::OUString& rQName, 61 const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList ); 62 63 // StartElement is called after a context has been constructed and 64 // before a elements context is parsed. It may be used for actions that 65 // require virtual methods. The default is to do nothing. 66 virtual void StartElement( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList ); 67 68 // EndElement is called before a context will be destructed, but 69 // after a elements context has been parsed. It may be used for actions 70 // that require virtual methods. The default is to do nothing. 71 virtual void EndElement(); 72 73 // This method is called for all characters that are contained in the 74 // current element. The default is to ignore them. 75 virtual void Characters( const ::rtl::OUString& rChars ); 76 }; 77 78 TYPEINIT1( XMLParagraphTransformerContext, XMLTransformerContext ); 79 80 XMLParagraphTransformerContext::XMLParagraphTransformerContext( 81 XMLTransformerBase& rImp, 82 const OUString& rQName ) : 83 XMLTransformerContext( rImp, rQName ) 84 { 85 } 86 87 XMLParagraphTransformerContext::~XMLParagraphTransformerContext() 88 { 89 } 90 91 XMLTransformerContext *XMLParagraphTransformerContext::CreateChildContext( 92 sal_uInt16 /*nPrefix*/, 93 const OUString& /*rLocalName*/, 94 const OUString& rQName, 95 const Reference< XAttributeList >& ) 96 { 97 XMLTransformerContext *pContext = 0; 98 99 pContext = new XMLIgnoreTransformerContext( GetTransformer(), 100 rQName, sal_True ); 101 102 return pContext; 103 } 104 105 void XMLParagraphTransformerContext::StartElement( const Reference< XAttributeList >& rAttrList ) 106 { 107 XMLTransformerContext::StartElement( rAttrList ); 108 } 109 110 void XMLParagraphTransformerContext::EndElement() 111 { 112 XMLTransformerContext::EndElement(); 113 } 114 115 void XMLParagraphTransformerContext::Characters( const OUString& rChars ) 116 { 117 XMLTransformerContext::Characters( rChars ); 118 } 119 120 class XMLPersTextContentRNGTransformTContext : public XMLPersTextContentTContext 121 { 122 public: 123 TYPEINFO(); 124 125 XMLPersTextContentRNGTransformTContext( 126 XMLTransformerBase& rTransformer, 127 const ::rtl::OUString& rQName, 128 sal_uInt16 nPrefix, 129 ::xmloff::token::XMLTokenEnum eToken ); 130 virtual ~XMLPersTextContentRNGTransformTContext(); 131 132 virtual void Characters( const ::rtl::OUString& rChars ); 133 }; 134 135 TYPEINIT1( XMLPersTextContentRNGTransformTContext, XMLPersAttrListTContext ); 136 137 XMLPersTextContentRNGTransformTContext::XMLPersTextContentRNGTransformTContext( 138 XMLTransformerBase& rTransformer, 139 const ::rtl::OUString& rQName, 140 sal_uInt16 nPrefix, 141 ::xmloff::token::XMLTokenEnum eToken ) : 142 XMLPersTextContentTContext( 143 rTransformer, rQName, nPrefix, eToken ) 144 {} 145 146 XMLPersTextContentRNGTransformTContext::~XMLPersTextContentRNGTransformTContext() 147 {} 148 149 void XMLPersTextContentRNGTransformTContext::Characters( const ::rtl::OUString& rChars ) 150 { 151 OUString aConvChars( rChars ); 152 GetTransformer().ConvertRNGDateTimeToISO( aConvChars ); 153 XMLPersTextContentTContext::Characters( aConvChars ); 154 } 155 156 157 TYPEINIT1( XMLMergeElemTransformerContext, XMLTransformerContext ); 158 159 void XMLMergeElemTransformerContext::ExportStartElement() 160 { 161 XMLPersTextContentTContextVector::iterator aIter = m_aChildContexts.begin(); 162 163 for( ; aIter != m_aChildContexts.end(); ++aIter ) 164 { 165 XMLPersTextContentTContext *pContext = (*aIter).get(); 166 static_cast< XMLMutableAttributeList * >( m_xAttrList.get() ) 167 ->AddAttribute( pContext->GetExportQName(), 168 pContext->GetTextContent() ); 169 } 170 XMLTransformerContext::StartElement( m_xAttrList ); 171 172 m_bStartElementExported = sal_True; 173 } 174 175 XMLMergeElemTransformerContext::XMLMergeElemTransformerContext( 176 XMLTransformerBase& rImp, 177 const OUString& rQName, 178 sal_uInt16 nActionMap ) : 179 XMLTransformerContext( rImp, rQName ), 180 m_nActionMap( nActionMap ), 181 m_bStartElementExported( sal_False ) 182 { 183 } 184 185 XMLMergeElemTransformerContext::~XMLMergeElemTransformerContext() 186 { 187 } 188 189 void XMLMergeElemTransformerContext::StartElement( 190 const Reference< XAttributeList >& rAttrList ) 191 { 192 XMLMutableAttributeList *pMutableAttrList = 193 new XMLMutableAttributeList( rAttrList, sal_True ); 194 m_xAttrList = pMutableAttrList; 195 196 sal_Int16 nAttrCount = m_xAttrList.is() ? m_xAttrList->getLength() : 0; 197 for( sal_Int16 i=0; i < nAttrCount; i++ ) 198 { 199 const OUString& rAttrName = m_xAttrList->getNameByIndex( i ); 200 OUString aLocalName; 201 sal_uInt16 nPrefix = 202 GetTransformer().GetNamespaceMap().GetKeyByAttrName( rAttrName, 203 &aLocalName ); 204 sal_Bool bRemove = sal_True; 205 if( XML_NAMESPACE_OFFICE == nPrefix) 206 { 207 if (IsXMLToken( aLocalName, XML_DISPLAY ) ) 208 bRemove = sal_False; 209 else if (IsXMLToken( aLocalName, XML_AUTHOR ) ) 210 bRemove = sal_False; 211 else if (IsXMLToken( aLocalName, XML_CREATE_DATE ) ) 212 bRemove = sal_False; 213 else if (IsXMLToken( aLocalName, XML_CREATE_DATE_STRING ) ) 214 bRemove = sal_False; 215 } 216 if (bRemove) 217 { 218 pMutableAttrList->RemoveAttributeByIndex( i ); 219 --i; 220 --nAttrCount; 221 } 222 } 223 } 224 225 XMLTransformerContext *XMLMergeElemTransformerContext::CreateChildContext( 226 sal_uInt16 nPrefix, 227 const OUString& rLocalName, 228 const OUString& rQName, 229 const Reference< XAttributeList >& rAttrList ) 230 { 231 XMLTransformerContext *pContext = 0; 232 233 if( !m_bStartElementExported ) 234 { 235 XMLTransformerActions *pActions = 236 GetTransformer().GetUserDefinedActions( m_nActionMap ); 237 OSL_ENSURE( pActions, "go no actions" ); 238 if( pActions ) 239 { 240 XMLTransformerActions::key_type aKey( nPrefix, rLocalName ); 241 XMLTransformerActions::const_iterator aIter = 242 pActions->find( aKey ); 243 244 if( !(aIter == pActions->end()) ) 245 { 246 switch( (*aIter).second.m_nActionType ) 247 { 248 case XML_ATACTION_MOVE_FROM_ELEM_RNG2ISO_DATETIME: 249 { 250 XMLPersTextContentTContext *pTC = 251 new XMLPersTextContentRNGTransformTContext( 252 GetTransformer(), rQName, 253 (*aIter).second.GetQNamePrefixFromParam1(), 254 (*aIter).second.GetQNameTokenFromParam1() ); 255 XMLPersTextContentTContextVector::value_type aVal(pTC); 256 m_aChildContexts.push_back( aVal ); 257 pContext = pTC; 258 } 259 break; 260 case XML_ATACTION_MOVE_FROM_ELEM: 261 { 262 XMLPersTextContentTContext *pTC = 263 new XMLPersTextContentTContext( 264 GetTransformer(), rQName, 265 (*aIter).second.GetQNamePrefixFromParam1(), 266 (*aIter).second.GetQNameTokenFromParam1() ); 267 XMLPersTextContentTContextVector::value_type aVal(pTC); 268 m_aChildContexts.push_back( aVal ); 269 pContext = pTC; 270 } 271 break; 272 case XML_ETACTION_EXTRACT_CHARACTERS: 273 { 274 if( !m_bStartElementExported ) 275 ExportStartElement(); 276 XMLParagraphTransformerContext* pPTC = 277 new XMLParagraphTransformerContext( GetTransformer(), 278 rQName); 279 pContext = pPTC; 280 } 281 break; 282 default: 283 OSL_ENSURE( !this, "unknown action" ); 284 break; 285 } 286 } 287 } 288 } 289 else 290 { 291 XMLTransformerActions *pActions = 292 GetTransformer().GetUserDefinedActions( m_nActionMap ); 293 OSL_ENSURE( pActions, "go no actions" ); 294 if( pActions ) 295 { 296 XMLTransformerActions::key_type aKey( nPrefix, rLocalName ); 297 XMLTransformerActions::const_iterator aIter = 298 pActions->find( aKey ); 299 300 if( !(aIter == pActions->end()) ) 301 { 302 switch( (*aIter).second.m_nActionType ) 303 { 304 case XML_ETACTION_EXTRACT_CHARACTERS: 305 { 306 if( !m_bStartElementExported ) 307 ExportStartElement(); 308 XMLParagraphTransformerContext* pPTC = 309 new XMLParagraphTransformerContext( GetTransformer(), 310 rQName); 311 pContext = pPTC; 312 } 313 break; 314 default: 315 OSL_ENSURE( !this, "unknown action" ); 316 break; 317 } 318 } 319 } 320 } 321 322 // default is copying 323 if( !pContext ) 324 { 325 if( !m_bStartElementExported ) 326 ExportStartElement(); 327 pContext = XMLTransformerContext::CreateChildContext( nPrefix, 328 rLocalName, 329 rQName, 330 rAttrList ); 331 } 332 333 return pContext; 334 } 335 336 void XMLMergeElemTransformerContext::EndElement() 337 { 338 if( !m_bStartElementExported ) 339 ExportStartElement(); 340 XMLTransformerContext::EndElement(); 341 } 342 343 void XMLMergeElemTransformerContext::Characters( const OUString& ) 344 { 345 // ignore 346 } 347