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_unotools.hxx"
26 
27 #include <unotools/xmlaccelcfg.hxx>
28 
29 #include <vector>
30 #include <com/sun/star/xml/sax/XAttributeList.hpp>
31 #include <cppuhelper/implbase1.hxx>
32 
33 using namespace rtl;
34 using namespace com::sun::star::uno;
35 using namespace com::sun::star::xml::sax;
36 
37 #define	ELEMENT_ACCELERATORLIST		"acceleratorlist"
38 #define ELEMENT_ACCELERATORITEM		"item"
39 
40 #define ATTRIBUTE_KEYCODE			"code"
41 #define ATTRIBUTE_MODIFIER			"modifier"
42 #define ATTRIBUTE_URL				"url"
43 
44 #define ATTRIBUTE_TYPE_CDATA		"CDATA"
45 
46 // ------------------------------------------------------------------
47 
48 struct AttributeListImpl_impl;
49 class AttributeListImpl : public ::cppu::WeakImplHelper1< ::com::sun::star::xml::sax::XAttributeList >
50 {
51 protected:
52 	~AttributeListImpl();
53 
54 public:
55 	AttributeListImpl();
56 	AttributeListImpl( const AttributeListImpl & );
57 
58 public:
59     virtual sal_Int16 SAL_CALL getLength(void) throw (::com::sun::star::uno::RuntimeException);
60     virtual ::rtl::OUString  SAL_CALL getNameByIndex(sal_Int16 i) throw (::com::sun::star::uno::RuntimeException);
61     virtual ::rtl::OUString  SAL_CALL getTypeByIndex(sal_Int16 i) throw (::com::sun::star::uno::RuntimeException);
62     virtual ::rtl::OUString  SAL_CALL getTypeByName(const ::rtl::OUString& aName) throw (::com::sun::star::uno::RuntimeException);
63     virtual ::rtl::OUString  SAL_CALL getValueByIndex(sal_Int16 i) throw (::com::sun::star::uno::RuntimeException);
64     virtual ::rtl::OUString  SAL_CALL getValueByName(const ::rtl::OUString& aName) throw (::com::sun::star::uno::RuntimeException);
65 
66 public:
67 	void addAttribute( const ::rtl::OUString &sName , const ::rtl::OUString &sType , const ::rtl::OUString &sValue );
68 	void clear();
69 
70 private:
71 	struct AttributeListImpl_impl *m_pImpl;
72 };
73 
74 struct TagAttribute
75 {
TagAttributeTagAttribute76 	TagAttribute(){}
TagAttributeTagAttribute77 	TagAttribute( const OUString &aName, const OUString &aType , const OUString &aValue )
78 	{
79 		sName 	= aName;
80 		sType 	= aType;
81 		sValue 	= aValue;
82 	}
83 
84 	OUString sName;
85 	OUString sType;
86 	OUString sValue;
87 };
88 
89 struct AttributeListImpl_impl
90 {
AttributeListImpl_implAttributeListImpl_impl91 	AttributeListImpl_impl()
92 	{
93 		// performance improvement during adding
94 		vecAttribute.reserve(20);
95 	}
96 	::std::vector<struct TagAttribute> vecAttribute;
97 };
98 
99 
100 
getLength(void)101 sal_Int16 SAL_CALL AttributeListImpl::getLength(void) throw (RuntimeException)
102 {
103 	return sal::static_int_cast< sal_Int16 >(m_pImpl->vecAttribute.size());
104 }
105 
106 
AttributeListImpl(const AttributeListImpl & r)107 AttributeListImpl::AttributeListImpl( const AttributeListImpl &r ) :
108     cppu::WeakImplHelper1<com::sun::star::xml::sax::XAttributeList>(r)
109 {
110 	m_pImpl = new AttributeListImpl_impl;
111 	*m_pImpl = *(r.m_pImpl);
112 }
113 
getNameByIndex(sal_Int16 i)114 OUString AttributeListImpl::getNameByIndex(sal_Int16 i) throw (RuntimeException)
115 {
116 	if( i < sal::static_int_cast<sal_Int16>(m_pImpl->vecAttribute.size()) ) {
117 		return m_pImpl->vecAttribute[i].sName;
118 	}
119 	return OUString();
120 }
121 
122 
getTypeByIndex(sal_Int16 i)123 OUString AttributeListImpl::getTypeByIndex(sal_Int16 i) throw (RuntimeException)
124 {
125 	if( i < sal::static_int_cast<sal_Int16>(m_pImpl->vecAttribute.size()) ) {
126 		return m_pImpl->vecAttribute[i].sType;
127 	}
128 	return OUString();
129 }
130 
getValueByIndex(sal_Int16 i)131 OUString AttributeListImpl::getValueByIndex(sal_Int16 i) throw (RuntimeException)
132 {
133 	if( i < sal::static_int_cast<sal_Int16>(m_pImpl->vecAttribute.size()) ) {
134 		return m_pImpl->vecAttribute[i].sValue;
135 	}
136 	return OUString();
137 
138 }
139 
getTypeByName(const OUString & sName)140 OUString AttributeListImpl::getTypeByName( const OUString& sName ) throw (RuntimeException)
141 {
142 	::std::vector<struct TagAttribute>::iterator ii = m_pImpl->vecAttribute.begin();
143 
144 	for( ; ii != m_pImpl->vecAttribute.end() ; ii ++ ) {
145 		if( (*ii).sName == sName ) {
146 			return (*ii).sType;
147 		}
148 	}
149 	return OUString();
150 }
151 
getValueByName(const OUString & sName)152 OUString AttributeListImpl::getValueByName(const OUString& sName) throw (RuntimeException)
153 {
154 	::std::vector<struct TagAttribute>::iterator ii = m_pImpl->vecAttribute.begin();
155 
156 	for( ; ii != m_pImpl->vecAttribute.end() ; ii ++ ) {
157 		if( (*ii).sName == sName ) {
158 			return (*ii).sValue;
159 		}
160 	}
161 	return OUString();
162 }
163 
164 
AttributeListImpl()165 AttributeListImpl::AttributeListImpl()
166 {
167 	m_pImpl = new AttributeListImpl_impl;
168 }
169 
170 
171 
~AttributeListImpl()172 AttributeListImpl::~AttributeListImpl()
173 {
174 	delete m_pImpl;
175 }
176 
177 
addAttribute(const OUString & sName,const OUString & sType,const OUString & sValue)178 void AttributeListImpl::addAttribute( 	const OUString &sName ,
179 										const OUString &sType ,
180 										const OUString &sValue )
181 {
182 	m_pImpl->vecAttribute.push_back( TagAttribute( sName , sType , sValue ) );
183 }
184 
clear()185 void AttributeListImpl::clear()
186 {
187 	::std::vector<struct TagAttribute> dummy;
188 	m_pImpl->vecAttribute.swap( dummy );
189 
190 	OSL_ASSERT( ! getLength() );
191 }
192 
193 // ------------------------------------------------------------------
194 
queryInterface(const Type & rType)195 Any SAL_CALL OReadAccelatorDocumentHandler::queryInterface( const Type & rType ) throw( RuntimeException )
196 {
197 	Any a = ::cppu::queryInterface( rType ,SAL_STATIC_CAST( XDocumentHandler*, this ));
198 	if ( a.hasValue() )
199 		return a;
200 	else
201 		return OWeakObject::queryInterface( rType );
202 }
203 
ignorableWhitespace(const OUString &)204 void SAL_CALL OReadAccelatorDocumentHandler::ignorableWhitespace(
205 	const OUString& )
206 throw( SAXException, RuntimeException )
207 {
208 }
209 
processingInstruction(const OUString &,const OUString &)210 void SAL_CALL OReadAccelatorDocumentHandler::processingInstruction(
211 	const OUString&, const OUString& )
212 throw( SAXException, RuntimeException )
213 {
214 }
215 
setDocumentLocator(const Reference<XLocator> & xLocator)216 void SAL_CALL OReadAccelatorDocumentHandler::setDocumentLocator(
217 	const Reference< XLocator > &xLocator)
218 throw(	SAXException, RuntimeException )
219 {
220 	m_xLocator = xLocator;
221 }
222 
getErrorLineString()223 ::rtl::OUString OReadAccelatorDocumentHandler::getErrorLineString()
224 {
225 	char buffer[32];
226 
227 	if ( m_xLocator.is() )
228 	{
229 		return OUString::createFromAscii( buffer );
230 	}
231 	else
232 		return OUString();
233 }
234 
startDocument(void)235 void SAL_CALL OReadAccelatorDocumentHandler::startDocument(void)
236 	throw ( SAXException, RuntimeException )
237 {
238 }
239 
endDocument(void)240 void SAL_CALL OReadAccelatorDocumentHandler::endDocument(void)
241 	throw( SAXException, RuntimeException )
242 {
243 	if ( m_nElementDepth > 0 )
244 	{
245 		OUString aErrorMessage = getErrorLineString();
246 		aErrorMessage += OUString( RTL_CONSTASCII_USTRINGPARAM( "A closing element is missing!" ));
247 		throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
248 	}
249 }
250 
251 
startElement(const OUString & aElementName,const Reference<XAttributeList> & xAttrList)252 void SAL_CALL OReadAccelatorDocumentHandler::startElement(
253 	const OUString& aElementName, const Reference< XAttributeList > &xAttrList )
254 throw( SAXException, RuntimeException )
255 {
256 	m_nElementDepth++;
257 
258 	if ( aElementName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_ACCELERATORLIST )))
259 	{
260 		// acceleratorlist
261 		if ( m_bAcceleratorMode )
262 		{
263 			OUString aErrorMessage = getErrorLineString();
264 			aErrorMessage += OUString( RTL_CONSTASCII_USTRINGPARAM( "Accelerator list used twice!" ));
265 			throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
266 		}
267 		else
268 			m_bAcceleratorMode = sal_True;
269 	}
270 	else if ( aElementName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_ACCELERATORITEM )))
271 	{
272 		// accelerator item
273 		if ( !m_bAcceleratorMode )
274 		{
275 			OUString aErrorMessage = getErrorLineString();
276 			aErrorMessage += OUString( RTL_CONSTASCII_USTRINGPARAM( "Accelerator list element has to be used before!" ));
277 			throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
278 		}
279 		else
280 		{
281 			// read accelerator item
282 			m_bItemCloseExpected = sal_True;
283 
284 			SvtAcceleratorConfigItem aItem;
285 
286 			// read attributes for accelerator
287 			for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ )
288 			{
289 				OUString aName = xAttrList->getNameByIndex( i );
290 				OUString aValue = xAttrList->getValueByIndex( i );
291 
292 				if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_URL )))
293                     aItem.aCommand = aValue;
294 				else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_MODIFIER )))
295 					aItem.nModifier = (sal_uInt16)aValue.toInt32();
296 				else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_KEYCODE )))
297 					aItem.nCode = (sal_uInt16)aValue.toInt32();
298 			}
299 
300 			m_aReadAcceleratorList.push_back( aItem );
301 		}
302 	}
303 	else
304 	{
305 		OUString aErrorMessage = getErrorLineString();
306 		aErrorMessage += OUString( RTL_CONSTASCII_USTRINGPARAM( "Unknown element found!" ));
307 		throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
308 	}
309 }
310 
311 
characters(const rtl::OUString &)312 void SAL_CALL OReadAccelatorDocumentHandler::characters(const rtl::OUString&)
313 throw(	SAXException, RuntimeException )
314 {
315 }
316 
317 
endElement(const OUString & aName)318 void SAL_CALL OReadAccelatorDocumentHandler::endElement( const OUString& aName )
319 	throw( SAXException, RuntimeException )
320 {
321 	m_nElementDepth--;
322 
323 	if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_ACCELERATORLIST )))
324 	{
325 		// acceleratorlist
326 		if ( !m_bAcceleratorMode )
327 		{
328 			OUString aErrorMessage = getErrorLineString();
329 			aErrorMessage += OUString( RTL_CONSTASCII_USTRINGPARAM( "Accelerator list used twice!" ));
330 			throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
331 		}
332 	}
333 	else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_ACCELERATORITEM )))
334 	{
335 		if ( !m_bItemCloseExpected )
336 		{
337 			OUString aErrorMessage = getErrorLineString();
338 			aErrorMessage += OUString( RTL_CONSTASCII_USTRINGPARAM( "Closing accelerator item element expected!" ));
339 			throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
340 		}
341 	}
342 	else
343 	{
344 		OUString aErrorMessage = getErrorLineString();
345 		aErrorMessage += OUString( RTL_CONSTASCII_USTRINGPARAM( "Unknown closing element found!" ));
346 		throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
347 	}
348 }
349 
350 // ------------------------------------------------------------------
351 
OWriteAccelatorDocumentHandler(const SvtAcceleratorItemList & aWriteAcceleratorList,Reference<XDocumentHandler> xDocumentHandler)352 OWriteAccelatorDocumentHandler::OWriteAccelatorDocumentHandler(
353 	const SvtAcceleratorItemList& aWriteAcceleratorList, Reference< XDocumentHandler > xDocumentHandler ) :
354 	m_xWriteDocumentHandler( xDocumentHandler ),
355 	m_aWriteAcceleratorList( aWriteAcceleratorList )
356 {
357 	m_aAttributeType = OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE_CDATA ));
358 }
359 
~OWriteAccelatorDocumentHandler()360 OWriteAccelatorDocumentHandler::~OWriteAccelatorDocumentHandler()
361 {
362 }
363 
WriteAcceleratorDocument()364 void OWriteAccelatorDocumentHandler::WriteAcceleratorDocument()
365 	throw ( SAXException, RuntimeException )
366 {
367 	AttributeListImpl* pList = new AttributeListImpl;
368 	Reference< XAttributeList > rList( (XAttributeList *)pList , UNO_QUERY );
369 
370 	m_xWriteDocumentHandler->startDocument();
371 	m_xWriteDocumentHandler->startElement( OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_ACCELERATORLIST )), rList );
372 	m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
373 
374 	std::list< SvtAcceleratorConfigItem>::const_iterator p;
375 	for ( p = m_aWriteAcceleratorList.begin(); p != m_aWriteAcceleratorList.end(); p++ )
376 		WriteAcceleratorItem( *p );
377 
378 	m_xWriteDocumentHandler->endElement( OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_ACCELERATORLIST )) );
379 	m_xWriteDocumentHandler->endDocument();
380 }
381 
WriteAcceleratorItem(const SvtAcceleratorConfigItem & aAcceleratorItem)382 void OWriteAccelatorDocumentHandler::WriteAcceleratorItem(
383 	const SvtAcceleratorConfigItem& aAcceleratorItem )
384 	throw( SAXException, RuntimeException )
385 {
386 	AttributeListImpl* pAcceleratorAttributes = new AttributeListImpl;
387 	Reference< XAttributeList > xAcceleratorAttrList( (XAttributeList *)pAcceleratorAttributes , UNO_QUERY );
388 
389 	// set attributes
390 	pAcceleratorAttributes->addAttribute(
391 		OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_KEYCODE )),
392 		m_aAttributeType,
393 		OUString::valueOf( aAcceleratorItem.nCode ));
394 
395 	pAcceleratorAttributes->addAttribute(
396 		OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MODIFIER )),
397 		m_aAttributeType,
398 		OUString::valueOf( aAcceleratorItem.nModifier ));
399 
400 	pAcceleratorAttributes->addAttribute(
401 		OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_URL )),
402 		m_aAttributeType,
403         aAcceleratorItem.aCommand );
404 
405 	// write start element
406 	m_xWriteDocumentHandler->startElement(
407 		OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_ACCELERATORITEM )),
408 		xAcceleratorAttrList );
409 	m_xWriteDocumentHandler->ignorableWhitespace( OUString() );
410 	m_xWriteDocumentHandler->endElement( OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_ACCELERATORITEM )) );
411 }
412