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 "MutableAttrList.hxx"
31 #include "xmloff/xmlnmspe.hxx"
32 #include <xmloff/nmspmap.hxx>
33 #include "IgnoreTContext.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 "FormPropOOoTContext.hxx"
43 
44 using ::rtl::OUString;
45 using namespace ::com::sun::star::uno;
46 using namespace ::com::sun::star::xml::sax;
47 using namespace ::xmloff::token;
48 
49 class XMLFormPropValueTContext_Impl : public XMLTransformerContext
50 {
51 	OUString m_aAttrQName;
52 	::rtl::OUString m_aCharacters;
53 	sal_Bool m_bPersistent;
54 	sal_Bool m_bIsVoid;
55 
56 public:
57 	TYPEINFO();
58 
59 	// element content persistence only
60 	XMLFormPropValueTContext_Impl( XMLTransformerBase& rTransformer,
61 						   const OUString& rQName );
62 	XMLFormPropValueTContext_Impl( XMLTransformerBase& rTransformer,
63 						   const OUString& rQName,
64 		   				   sal_uInt16 nAttrPrefix,
65 						   XMLTokenEnum eAttrToken );
66 
67 	virtual ~XMLFormPropValueTContext_Impl();
68 
69 	virtual void StartElement( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList );
70 
71 	virtual void EndElement();
72 
73 	virtual void Characters( const ::rtl::OUString& rChars );
74 
75 	virtual sal_Bool IsPersistent() const;
76 
77 	sal_Bool IsVoid() const { return m_bIsVoid; }
78 	const ::rtl::OUString& GetTextContent() const { return m_aCharacters; }
79 };
80 
81 TYPEINIT1( XMLFormPropValueTContext_Impl, XMLTransformerContext );
82 
83 XMLFormPropValueTContext_Impl::XMLFormPropValueTContext_Impl(
84 		XMLTransformerBase& rTransformer,
85 		const ::rtl::OUString& rQName ) :
86 	XMLTransformerContext( rTransformer, rQName ),
87 	m_bPersistent( sal_True ),
88 	m_bIsVoid( sal_False )
89 {
90 }
91 
92 XMLFormPropValueTContext_Impl::XMLFormPropValueTContext_Impl(
93 		XMLTransformerBase& rTransformer,
94 		const ::rtl::OUString& rQName,
95 	    sal_uInt16 nAttrPrefix,
96 	    XMLTokenEnum eAttrToken ) :
97 	XMLTransformerContext( rTransformer, rQName ),
98 	m_aAttrQName( rTransformer.GetNamespaceMap().GetQNameByKey(
99 					nAttrPrefix, GetXMLToken(eAttrToken) ) ),
100 	m_bPersistent( sal_True ),
101 	m_bIsVoid( sal_False )
102 {
103 }
104 
105 XMLFormPropValueTContext_Impl::~XMLFormPropValueTContext_Impl()
106 {
107 }
108 
109 void XMLFormPropValueTContext_Impl::StartElement(
110 	const Reference< XAttributeList >& rAttrList )
111 {
112 	sal_Int16 nAttrCount = rAttrList.is() ? rAttrList->getLength() : 0;
113 	for( sal_Int16 i=0; i < nAttrCount; i++ )
114 	{
115 		const OUString& rAttrName = rAttrList->getNameByIndex( i );
116 		OUString aLocalName;
117 		sal_uInt16 nPrefix =
118 			GetTransformer().GetNamespaceMap().GetKeyByAttrName( rAttrName,
119 																 &aLocalName );
120 		if( XML_NAMESPACE_FORM == nPrefix &&
121 			IsXMLToken( aLocalName, XML_PROPERTY_IS_VOID ) &&
122 		 	IsXMLToken( rAttrList->getValueByIndex( i ), XML_TRUE ) )
123 			m_bIsVoid = sal_True;
124 	}
125 }
126 
127 void XMLFormPropValueTContext_Impl::EndElement()
128 {
129 	if( !m_bPersistent )
130 	{
131 		XMLMutableAttributeList *pMutableAttrList =
132 			new XMLMutableAttributeList;
133 		Reference< XAttributeList > xAttrList( pMutableAttrList );
134 		pMutableAttrList->AddAttribute( m_aAttrQName,
135 										m_aCharacters );
136 
137 		OUString aElemQName( GetTransformer().GetNamespaceMap().GetQNameByKey(
138 					XML_NAMESPACE_FORM, GetXMLToken(XML_LIST_VALUE) ) );
139 		GetTransformer().GetDocHandler()->startElement( aElemQName,
140 													xAttrList );
141 		GetTransformer().GetDocHandler()->endElement( aElemQName );
142 	}
143 }
144 
145 void XMLFormPropValueTContext_Impl::Characters( const OUString& rChars )
146 {
147 	m_aCharacters += rChars;
148 }
149 
150 
151 sal_Bool XMLFormPropValueTContext_Impl::IsPersistent() const
152 {
153 	return m_bPersistent;
154 }
155 
156 //------------------------------------------------------------------------------
157 
158 TYPEINIT1( XMLFormPropOOoTransformerContext, XMLTransformerContext );
159 
160 XMLFormPropOOoTransformerContext::XMLFormPropOOoTransformerContext(
161 		XMLTransformerBase& rImp,
162 		const OUString& rQName ) :
163 	XMLTransformerContext( rImp, rQName ),
164 	m_aElemQName( rQName ),
165 	m_nValueTypeAttr( -1 ),
166 	m_eValueToken( XML_VALUE ),
167 	m_eValueTypeToken( XML_TOKEN_END ),
168 	m_bIsList( sal_False )
169 {
170 }
171 
172 XMLFormPropOOoTransformerContext::~XMLFormPropOOoTransformerContext()
173 {
174 }
175 
176 XMLTransformerContext *XMLFormPropOOoTransformerContext::CreateChildContext(
177 		sal_uInt16 nPrefix,
178 		const OUString& rLocalName,
179 		const OUString& rQName,
180 		const Reference< XAttributeList >& )
181 {
182 	XMLTransformerContext *pContext = 0;
183 
184 	if( XML_NAMESPACE_FORM == nPrefix &&
185 		IsXMLToken( rLocalName, XML_PROPERTY_VALUE ) )
186 	{
187 		if( m_bIsList )
188 		{
189 			pContext = new XMLFormPropValueTContext_Impl( GetTransformer(),
190 														  rQName,
191 														  XML_NAMESPACE_OFFICE,
192 														  m_eValueToken );
193 		}
194 		else if( !m_xValueContext.is() )
195 		{
196 			m_xValueContext=
197 				new XMLFormPropValueTContext_Impl( GetTransformer(), rQName );
198 			pContext = m_xValueContext.get();
199 		}
200 	}
201 
202 	// default is ignore
203 	if( !pContext )
204 		pContext = new XMLIgnoreTransformerContext( GetTransformer(), rQName,
205 			   							  sal_True, sal_True );
206 	return pContext;
207 }
208 
209 void XMLFormPropOOoTransformerContext::StartElement(
210 	const Reference< XAttributeList >& rAttrList )
211 {
212 
213 	XMLTransformerActions *pActions =
214 		GetTransformer().GetUserDefinedActions( OOO_FORM_PROP_ACTIONS );
215 	OSL_ENSURE( pActions, "go no actions" );
216 
217 	XMLMutableAttributeList *pMutableAttrList =
218 		new XMLMutableAttributeList( rAttrList, sal_True );
219 	m_xAttrList = pMutableAttrList;
220 
221 	OUString aValueType;
222 	sal_Int16 nAttrCount = rAttrList.is() ? rAttrList->getLength() : 0;
223 	for( sal_Int16 i=0; i < nAttrCount; i++ )
224 	{
225 		const OUString& rAttrName = rAttrList->getNameByIndex( i );
226 		OUString aLocalName;
227 		sal_uInt16 nPrefix =
228 			GetTransformer().GetNamespaceMap().GetKeyByAttrName( rAttrName,
229 																 &aLocalName );
230 		XMLTransformerActions::key_type aKey( nPrefix, aLocalName );
231 		XMLTransformerActions::const_iterator aIter =
232 			pActions->find( aKey );
233 		if( !(aIter == pActions->end() ) )
234 		{
235 			const OUString& rAttrValue = rAttrList->getValueByIndex( i );
236 			switch( (*aIter).second.m_nActionType )
237 			{
238 			case XML_ATACTION_RENAME:
239 				if( IsXMLToken( aLocalName, XML_PROPERTY_TYPE ) )
240 				{
241 					aValueType = rAttrValue;
242 					m_nValueTypeAttr = i;
243 				}
244 				{
245 					OUString aNewAttrQName(
246 						GetTransformer().GetNamespaceMap().GetQNameByKey(
247 								(*aIter).second.GetQNamePrefixFromParam1(),
248 								::xmloff::token::GetXMLToken(
249 									(*aIter).second.GetQNameTokenFromParam1()) ) );
250 					pMutableAttrList->RenameAttributeByIndex( i, aNewAttrQName );
251 				}
252 				break;
253 			case XML_ATACTION_REMOVE:
254 				if( IsXMLToken( aLocalName, XML_PROPERTY_IS_LIST ) )
255 				{
256 					m_aElemQName =
257 						GetTransformer().GetNamespaceMap().GetQNameByKey(
258 						XML_NAMESPACE_FORM, GetXMLToken( XML_LIST_PROPERTY ) );
259 					m_bIsList = sal_True;
260 				}
261 				pMutableAttrList->RemoveAttributeByIndex( i );
262 				--i;
263 				--nAttrCount;
264 				break;
265 			default:
266 				OSL_ENSURE( !this, "unknown action" );
267 				break;
268 			}
269 		}
270 	}
271 
272 	if( aValueType.getLength() )
273 	{
274 		if( IsXMLToken( aValueType, XML_STRING ) )
275 			m_eValueToken = XML_STRING_VALUE;
276 		else if( IsXMLToken( aValueType, XML_BOOLEAN ) )
277 			m_eValueToken = XML_BOOLEAN_VALUE;
278 		else if( IsXMLToken( aValueType, XML_SHORT ) ||
279 				 IsXMLToken( aValueType, XML_INT ) ||
280 				 IsXMLToken( aValueType, XML_LONG ) ||
281 				 IsXMLToken( aValueType, XML_DOUBLE ) )
282 			m_eValueTypeToken = XML_FLOAT;
283 	}
284 }
285 
286 void XMLFormPropOOoTransformerContext::EndElement()
287 {
288 	if( m_xValueContext.is() )
289 	{
290 		if( m_xValueContext->IsVoid() )
291 		{
292 			m_eValueTypeToken = XML_VOID;
293 		}
294 		else
295 		{
296 			OUString aAttrQName(
297 					GetTransformer().GetNamespaceMap().GetQNameByKey(
298 					XML_NAMESPACE_OFFICE, GetXMLToken(m_eValueToken) ) );
299 			static_cast< XMLMutableAttributeList * >( m_xAttrList.get() )
300 				->AddAttribute( aAttrQName, m_xValueContext->GetTextContent() );
301 		}
302 	}
303 
304 	if( m_nValueTypeAttr != -1 && m_eValueTypeToken != XML_TOKEN_END )
305 	{
306 		static_cast< XMLMutableAttributeList * >( m_xAttrList.get() )
307 			->SetValueByIndex( m_nValueTypeAttr ,
308 								GetXMLToken( m_eValueTypeToken ) );
309 	}
310 
311 	GetTransformer().GetDocHandler()->startElement( m_aElemQName,
312 													m_xAttrList );
313 	GetTransformer().GetDocHandler()->endElement( m_aElemQName );
314 }
315