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