xref: /trunk/main/xmloff/source/transform/MergeElemTContext.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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