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