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 "EventOOoTContext.hxx"
31 #include "EventMap.hxx"
32 #include "MutableAttrList.hxx"
33 #include "xmloff/xmlnmspe.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 <comphelper/stl_types.hxx>
43 #include <rtl/ustrbuf.hxx>
44 
45 #include <hash_map>
46 
47 using ::rtl::OUString;
48 using ::rtl::OUStringBuffer;
49 using namespace ::com::sun::star::uno;
50 using namespace ::com::sun::star::xml::sax;
51 using namespace ::xmloff::token;
52 
53 class XMLTransformerOOoEventMap_Impl:
54 	public ::std::hash_map< ::rtl::OUString, NameKey_Impl,
55 						    ::rtl::OUStringHash, ::comphelper::UStringEqual >
56 {
57 public:
58 
59 	void AddMap( XMLTransformerEventMapEntry *pInit );
60 
61 	XMLTransformerOOoEventMap_Impl( XMLTransformerEventMapEntry *pInit,
62 		   							XMLTransformerEventMapEntry *pInit2	);
63 	~XMLTransformerOOoEventMap_Impl();
64 };
65 
66 void XMLTransformerOOoEventMap_Impl::AddMap( XMLTransformerEventMapEntry *pInit )
67 {
68 	XMLTransformerOOoEventMap_Impl::key_type aKey;
69 	XMLTransformerOOoEventMap_Impl::data_type aData;
70 	while( pInit->m_pOOoName )
71 	{
72 		aKey = OUString::createFromAscii(pInit->m_pOOoName);
73 
74 		OSL_ENSURE( find( aKey ) == end(), "duplicate event map entry" );
75 
76 		aData.m_nPrefix = pInit->m_nOASISPrefix;
77 		aData.m_aLocalName = OUString::createFromAscii(pInit->m_pOASISName);
78 
79 		XMLTransformerOOoEventMap_Impl::value_type aVal( aKey, aData );
80 
81 		if( !insert( aVal ).second )
82 		{
83 			OSL_ENSURE( false, "duplicate OOo event name extry" );
84 		}
85 
86 		++pInit;
87 	}
88 }
89 
90 XMLTransformerOOoEventMap_Impl::XMLTransformerOOoEventMap_Impl(
91 		XMLTransformerEventMapEntry *pInit,
92 	    XMLTransformerEventMapEntry *pInit2	)
93 {
94 	if( pInit )
95 		AddMap( pInit );
96 	if( pInit )
97 		AddMap( pInit2 );
98 }
99 
100 XMLTransformerOOoEventMap_Impl::~XMLTransformerOOoEventMap_Impl()
101 {
102 }
103 
104 // -----------------------------------------------------------------------------
105 
106 TYPEINIT1( XMLEventOOoTransformerContext, XMLPersElemContentTContext );
107 
108 XMLEventOOoTransformerContext::XMLEventOOoTransformerContext(
109 		XMLTransformerBase& rImp,
110 		const OUString& rQName,
111 	    sal_Bool bPersistent ) :
112 	XMLPersElemContentTContext( rImp, rQName,
113 		rImp.GetNamespaceMap().GetKeyByAttrName( rQName ), XML_EVENT_LISTENER ),
114 	m_bPersistent( bPersistent )
115 {
116 }
117 
118 XMLEventOOoTransformerContext::~XMLEventOOoTransformerContext()
119 {
120 }
121 
122 XMLTransformerOOoEventMap_Impl
123 	*XMLEventOOoTransformerContext::CreateEventMap()
124 {
125 	return new XMLTransformerOOoEventMap_Impl( aTransformerEventMap,
126 		   									   aFormTransformerEventMap );
127 }
128 
129 void XMLEventOOoTransformerContext::FlushEventMap(
130 		XMLTransformerOOoEventMap_Impl *p )
131 {
132 	delete p;
133 }
134 
135 sal_uInt16 XMLEventOOoTransformerContext::GetEventName(
136 		const OUString& rName,
137 		OUString& rNewName,
138 	   	XMLTransformerOOoEventMap_Impl& rMap )
139 {
140 	XMLTransformerOOoEventMap_Impl::key_type aKey( rName );
141 	XMLTransformerOOoEventMap_Impl::const_iterator aIter = rMap.find( aKey );
142 	if( aIter == rMap.end() )
143 	{
144 		rNewName = rName;
145 		return XML_NAMESPACE_UNKNOWN;
146 	}
147 	else
148 	{
149 		rNewName = (*aIter).second.m_aLocalName;
150 		return (*aIter).second.m_nPrefix;
151 	}
152 }
153 
154 
155 void XMLEventOOoTransformerContext::StartElement(
156 	const Reference< XAttributeList >& rAttrList )
157 {
158 	XMLTransformerActions *pActions =
159 		GetTransformer().GetUserDefinedActions( OOO_EVENT_ACTIONS );
160 	OSL_ENSURE( pActions, "go no actions" );
161 
162 	OUString aLocation, aMacroName;
163 	sal_Int16 nMacroName = -1;
164 	Reference< XAttributeList > xAttrList( rAttrList );
165 	XMLMutableAttributeList *pMutableAttrList = 0;
166 	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
167 	for( sal_Int16 i=0; i < nAttrCount; i++ )
168 	{
169 		const OUString& rAttrName = xAttrList->getNameByIndex( i );
170 		OUString aLocalName;
171 		sal_uInt16 nPrefix =
172 			GetTransformer().GetNamespaceMap().GetKeyByAttrName( rAttrName,
173 																 &aLocalName );
174 		XMLTransformerActions::key_type aKey( nPrefix, aLocalName );
175 		XMLTransformerActions::const_iterator aIter =
176 			pActions->find( aKey );
177 		if( !(aIter == pActions->end() ) )
178 		{
179 			if( !pMutableAttrList )
180 			{
181 				pMutableAttrList =
182 						new XMLMutableAttributeList( xAttrList );
183 				xAttrList = pMutableAttrList;
184 			}
185 			const OUString& rAttrValue = xAttrList->getValueByIndex( i );
186 			switch( (*aIter).second.m_nActionType )
187 			{
188 			case XML_ATACTION_HREF:
189 				// TODO
190 				break;
191 			case XML_ATACTION_EVENT_NAME:
192 				pMutableAttrList->SetValueByIndex( i,
193 							   GetTransformer().GetEventName( rAttrValue ) );
194 				break;
195 			case XML_ATACTION_ADD_NAMESPACE_PREFIX:
196 				{
197 					OUString aAttrValue( rAttrValue );
198 					sal_uInt16 nValPrefix =
199 						static_cast<sal_uInt16>((*aIter).second.m_nParam1);
200 					if( GetTransformer().AddNamespacePrefix( aAttrValue,
201 															 nValPrefix ) )
202 						pMutableAttrList->SetValueByIndex( i, aAttrValue );
203 				}
204 				break;
205 			case XML_ATACTION_MACRO_LOCATION:
206 				aLocation = rAttrValue;
207 				pMutableAttrList->RemoveAttributeByIndex( i );
208 				--i;
209 				--nAttrCount;
210 				break;
211 			case XML_ATACTION_MACRO_NAME:
212 				aMacroName = rAttrValue;
213 				nMacroName = i;
214 				break;
215 			case XML_ATACTION_COPY:
216 				break;
217 			default:
218 				OSL_ENSURE( !this, "unknown action" );
219 				break;
220 			}
221 		}
222 	}
223 
224 	if( nMacroName != -1 && aLocation.getLength() > 0 )
225 	{
226 		if( !IsXMLToken( aLocation, XML_APPLICATION ) )
227 			aLocation = GetXMLToken( XML_DOCUMENT );
228 		OUStringBuffer sTmp( aLocation.getLength() + aMacroName.getLength() + 1 );
229 		sTmp = aLocation;
230 		sTmp.append( sal_Unicode( ':' ) );
231 		sTmp.append( aMacroName );
232 		pMutableAttrList->SetValueByIndex( nMacroName,
233 										   sTmp.makeStringAndClear() );
234 	}
235 
236 	if( m_bPersistent )
237 		XMLPersElemContentTContext::StartElement( xAttrList );
238 	else
239 		GetTransformer().GetDocHandler()->startElement( GetExportQName(),
240 														xAttrList );
241 }
242 
243 void XMLEventOOoTransformerContext::EndElement()
244 {
245 	if( m_bPersistent )
246 		XMLPersElemContentTContext::EndElement();
247 	else
248 		GetTransformer().GetDocHandler()->endElement( GetExportQName() );
249 }
250 
251 XMLTransformerContext * XMLEventOOoTransformerContext::CreateChildContext(
252 							sal_uInt16 nPrefix,
253 							const OUString& rLocalName,
254 							const OUString& rQName,
255 							const Reference< XAttributeList >& xAttrList )
256 {
257 	if( m_bPersistent )
258 		return XMLPersElemContentTContext::CreateChildContext(nPrefix, rLocalName, rQName, xAttrList);
259 	else
260 		return XMLTransformerContext::CreateChildContext(nPrefix, rLocalName, rQName, xAttrList);
261 }
262 
263 sal_Bool XMLEventOOoTransformerContext::IsPersistent() const
264 {
265 	return m_bPersistent;
266 }
267