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 "MutableAttrList.hxx"
27 #include "xmloff/xmlnmspe.hxx"
28 #include <xmloff/nmspmap.hxx>
29 #include "ActionMapTypesOASIS.hxx"
30 #include "AttrTransformerAction.hxx"
31 #include "TransformerActions.hxx"
32 #ifndef _XMLOFF_TRANSFORMERBASE_HXX
33 #include "TransformerBase.hxx"
34 #endif
35 #include "FormPropOASISTContext.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 TYPEINIT1( XMLFormPropOASISTransformerContext,
43 				XMLRenameElemTransformerContext );
44 
45 XMLTokenEnum XMLFormPropOASISTransformerContext::GetValueType(
46 				const OUString& rValue )
47 {
48 	XMLTokenEnum eRet = XML_DOUBLE;
49     sal_Bool bNeg = sal_False;
50     sal_uInt32 nVal = 0;
51 
52     sal_Int32 nPos = 0;
53     sal_Int32 nLen = rValue.getLength();
54 
55     // skip white space
56     while( nPos < nLen && sal_Unicode(' ') == rValue[nPos] )
57         nPos++;
58 
59     if( nPos < nLen && sal_Unicode('-') == rValue[nPos] )
60     {
61         bNeg = sal_True;
62         nPos++;
63     }
64 
65     // get number
66 	sal_Bool bOverflow = sal_False;
67     while( nPos < nLen &&
68            sal_Unicode('0') <= rValue[nPos] &&
69            sal_Unicode('9') >= rValue[nPos] )
70     {
71         nVal *= 10;
72         nVal += (rValue[nPos] - sal_Unicode('0'));
73 		bOverflow |= (nVal > (bNeg ? 2147483648UL : 2147483647UL));
74         nPos++;
75     }
76 
77     // skip white space
78     while( nPos < nLen && sal_Unicode(' ') == rValue[nPos] )
79         nPos++;
80 
81 	if( nPos == nLen )
82 	{
83 		// It's a integer number
84 		if( bOverflow )
85 			eRet = XML_LONG;
86 		else if( nVal > (bNeg ? 32768UL : 32767UL) )
87 			eRet = XML_INT;
88 		else
89 			eRet = XML_SHORT;
90 	}
91 
92 	return eRet;
93 }
94 
95 XMLFormPropOASISTransformerContext::XMLFormPropOASISTransformerContext(
96 		XMLTransformerBase& rImp,
97 		const OUString& rQName,
98 	    XMLTokenEnum eLocalName ) :
99 	XMLRenameElemTransformerContext( rImp, rQName, XML_NAMESPACE_FORM,
100 		  							 XML_PROPERTY ),
101 	m_bIsList( XML_LIST_PROPERTY == eLocalName),
102 	m_bIsListValue( XML_LIST_VALUE == eLocalName)
103 {
104 }
105 
106 XMLFormPropOASISTransformerContext::~XMLFormPropOASISTransformerContext()
107 {
108 }
109 
110 void XMLFormPropOASISTransformerContext::StartElement(
111 	const Reference< XAttributeList >& rAttrList )
112 {
113 
114 	XMLTransformerActions *pActions =
115 		GetTransformer().GetUserDefinedActions( OASIS_FORM_PROP_ACTIONS );
116 	OSL_ENSURE( pActions, "go no actions" );
117 
118 	XMLMutableAttributeList *pMutableAttrList =
119 		new XMLMutableAttributeList( rAttrList );
120 	Reference< XAttributeList > xAttrList( pMutableAttrList );
121 
122 	sal_Int16 nValueTypeAttr = -1;
123 	OUString aValue;
124 	sal_Bool bIsVoid = sal_False;
125 	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
126 	for( sal_Int16 i=0; i < nAttrCount; i++ )
127 	{
128 		const OUString& rAttrName = xAttrList->getNameByIndex( i );
129 		OUString aLocalName;
130 		sal_uInt16 nPrefix =
131 			GetTransformer().GetNamespaceMap().GetKeyByAttrName( rAttrName,
132 																 &aLocalName );
133 		XMLTransformerActions::key_type aKey( nPrefix, aLocalName );
134 		XMLTransformerActions::const_iterator aIter =
135 			pActions->find( aKey );
136 		if( !(aIter == pActions->end() ) )
137 		{
138 			const OUString& rAttrValue = xAttrList->getValueByIndex( i );
139 			switch( (*aIter).second.m_nActionType )
140 			{
141 			case XML_ATACTION_RENAME:
142 				if( IsXMLToken( aLocalName, XML_VALUE_TYPE ) )
143 				{
144 					if( IsXMLToken( rAttrValue, XML_FLOAT ) )
145 					{
146 						nValueTypeAttr = i;
147 					}
148 					else if( IsXMLToken( rAttrValue, XML_VOID ) )
149 					{
150 						pMutableAttrList->SetValueByIndex( i,
151 								GetXMLToken( XML_SHORT ) );
152 						bIsVoid = sal_True;
153 					}
154 				}
155 				{
156 					OUString aNewAttrQName(
157 						GetTransformer().GetNamespaceMap().GetQNameByKey(
158 								(*aIter).second.GetQNamePrefixFromParam1(),
159 								::xmloff::token::GetXMLToken(
160 									(*aIter).second.GetQNameTokenFromParam1()) ) );
161 					pMutableAttrList->RenameAttributeByIndex( i, aNewAttrQName );
162 				}
163 				break;
164 			case XML_ATACTION_REMOVE:
165 				if( !IsXMLToken( aLocalName, XML_CURRENCY ) )
166 					aValue = rAttrValue;
167 				pMutableAttrList->RemoveAttributeByIndex( i );
168 				--i;
169 				--nAttrCount;
170 				break;
171 			default:
172 				OSL_ENSURE( !this, "unknown action" );
173 				break;
174 			}
175 		}
176 	}
177 	if( m_bIsList )
178 	{
179 		OUString aNewAttrQName(
180 				GetTransformer().GetNamespaceMap().GetQNameByKey(
181 					XML_NAMESPACE_FORM,
182 					GetXMLToken( XML_PROPERTY_IS_LIST ) ) );
183 		pMutableAttrList->AddAttribute( aNewAttrQName,
184 										GetXMLToken( XML_TRUE ) );
185 	}
186 
187 	if( nValueTypeAttr != -1 )
188 		pMutableAttrList->SetValueByIndex( nValueTypeAttr,
189 								GetXMLToken( GetValueType( aValue ) ) );
190 
191 	if( !m_bIsListValue )
192 		XMLRenameElemTransformerContext::StartElement( xAttrList );
193 	if( !m_bIsList )
194 	{
195 		pMutableAttrList =
196 			new XMLMutableAttributeList;
197 		xAttrList = pMutableAttrList;
198 		if( bIsVoid )
199 		{
200 			OUString aNewAttrQName(
201 				GetTransformer().GetNamespaceMap().GetQNameByKey(
202 					XML_NAMESPACE_FORM, GetXMLToken( XML_PROPERTY_IS_VOID ) ) );
203 			pMutableAttrList->AddAttribute( aNewAttrQName,
204 										GetXMLToken( XML_TRUE ) );
205 		}
206 
207 		OUString aValueElemQName(
208 			GetTransformer().GetNamespaceMap().GetQNameByKey(
209 					XML_NAMESPACE_FORM, GetXMLToken( XML_PROPERTY_VALUE ) ) );
210 		GetTransformer().GetDocHandler()->startElement( aValueElemQName,
211 														xAttrList );
212 		GetTransformer().GetDocHandler()->characters( aValue );
213 		GetTransformer().GetDocHandler()->endElement( aValueElemQName );
214 	}
215 }
216 
217 void XMLFormPropOASISTransformerContext::EndElement()
218 {
219 	if( !m_bIsListValue )
220 		XMLRenameElemTransformerContext::EndElement();
221 }
222