merge the formfield patch from ooo-build
[ooovba.git] / linguistic / source / convdicxml.cxx
blob772666a90c501f654653668e7e5681429be25b6c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: convdicxml.cxx,v $
10 * $Revision: 1.9 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_linguistic.hxx"
33 #include <tools/urlobj.hxx>
34 #include <tools/debug.hxx>
35 #include <tools/fsys.hxx>
36 #include <tools/string.hxx>
37 #include <i18npool/mslangid.hxx>
38 #include <tools/stream.hxx>
39 #include <sfx2/docfile.hxx>
40 #include <osl/mutex.hxx>
41 #include <unotools/processfactory.hxx>
42 #include <ucbhelper/content.hxx>
44 #include <cppuhelper/factory.hxx> // helper for factories
45 #include <com/sun/star/linguistic2/XConversionDictionary.hpp>
46 #include <com/sun/star/linguistic2/ConversionDictionaryType.hpp>
47 #include <com/sun/star/linguistic2/ConversionPropertyType.hpp>
48 #include <com/sun/star/util/XFlushable.hpp>
49 #include <com/sun/star/lang/Locale.hpp>
50 #include <com/sun/star/lang/EventObject.hpp>
51 #ifndef _COM_SUN_STAR_UNO_REFERENCE_HPP_
52 #include <com/sun/star/uno/Reference.h>
53 #endif
54 #include <com/sun/star/registry/XRegistryKey.hpp>
55 #include <com/sun/star/util/XFlushListener.hpp>
56 #include <com/sun/star/io/XActiveDataSource.hpp>
57 #include <com/sun/star/document/XFilter.hpp>
58 #include <com/sun/star/beans/PropertyValue.hpp>
59 #include <xmloff/nmspmap.hxx>
60 #include <xmloff/xmlnmspe.hxx>
61 #include <unotools/streamwrap.hxx>
63 #include "convdic.hxx"
64 #include "convdicxml.hxx"
65 #include "misc.hxx"
66 #include "defs.hxx"
68 using namespace std;
69 using namespace utl;
70 using namespace osl;
71 using namespace rtl;
72 using namespace com::sun::star;
73 using namespace com::sun::star::lang;
74 using namespace com::sun::star::uno;
75 using namespace com::sun::star::linguistic2;
76 using namespace linguistic;
78 #define XML_NAMESPACE_TCD_STRING "http://openoffice.org/2003/text-conversion-dictionary"
79 #define CONV_TYPE_HANGUL_HANJA "Hangul / Hanja"
80 #define CONV_TYPE_SCHINESE_TCHINESE "Chinese simplified / Chinese traditional"
82 ///////////////////////////////////////////////////////////////////////////
84 static const OUString ConversionTypeToText( sal_Int16 nConversionType )
86 OUString aRes;
87 if (nConversionType == ConversionDictionaryType::HANGUL_HANJA)
88 aRes = A2OU( CONV_TYPE_HANGUL_HANJA );
89 else if (nConversionType == ConversionDictionaryType::SCHINESE_TCHINESE)
90 aRes = A2OU( CONV_TYPE_SCHINESE_TCHINESE );
91 return aRes;
94 static sal_Int16 GetConversionTypeFromText( const String &rText )
96 sal_Int16 nRes = -1;
97 if (rText.EqualsAscii( CONV_TYPE_HANGUL_HANJA ))
98 nRes = ConversionDictionaryType::HANGUL_HANJA;
99 else if (rText.EqualsAscii( CONV_TYPE_SCHINESE_TCHINESE ))
100 nRes = ConversionDictionaryType::SCHINESE_TCHINESE;
101 return nRes;
104 ///////////////////////////////////////////////////////////////////////////
106 class ConvDicXMLImportContext :
107 public SvXMLImportContext
109 public:
110 ConvDicXMLImportContext(
111 ConvDicXMLImport &rImport,
112 sal_uInt16 nPrfx, const OUString& rLName ) :
113 SvXMLImportContext( rImport, nPrfx, rLName )
117 const ConvDicXMLImport & GetConvDicImport() const
119 return (const ConvDicXMLImport &) GetImport();
122 ConvDicXMLImport & GetConvDicImport()
124 return (ConvDicXMLImport &) GetImport();
127 // SvXMLImportContext
128 virtual void Characters( const OUString &rChars );
129 virtual SvXMLImportContext * CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference< xml::sax::XAttributeList > &rxAttrList);
133 class ConvDicXMLDictionaryContext_Impl :
134 public ConvDicXMLImportContext
136 INT16 nLanguage;
137 sal_Int16 nConversionType;
139 public:
140 ConvDicXMLDictionaryContext_Impl( ConvDicXMLImport &rImport,
141 sal_uInt16 nPrefix, const OUString& rLName) :
142 ConvDicXMLImportContext( rImport, nPrefix, rLName )
144 nLanguage = LANGUAGE_NONE;
145 nConversionType = -1;
148 // SvXMLImportContext
149 virtual void StartElement( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList );
150 virtual SvXMLImportContext * CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference< xml::sax::XAttributeList > &rxAttrList );
152 INT16 GetLanguage() const { return nLanguage; }
153 sal_Int16 GetConversionType() const { return nConversionType; }
157 class ConvDicXMLEntryTextContext_Impl :
158 public ConvDicXMLImportContext
160 OUString aLeftText;
161 sal_Int16 nPropertyType; // used for Chinese simplified/traditional conversion
162 ConvDicXMLDictionaryContext_Impl &rDicContext;
164 public:
165 ConvDicXMLEntryTextContext_Impl(
166 ConvDicXMLImport &rImport,
167 sal_uInt16 nPrefix, const OUString& rLName,
168 ConvDicXMLDictionaryContext_Impl &rParentContext ) :
169 ConvDicXMLImportContext( rImport, nPrefix, rLName ),
170 nPropertyType( ConversionPropertyType::NOT_DEFINED ),
171 rDicContext( rParentContext )
175 // SvXMLImportContext
176 virtual void StartElement( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList );
177 virtual SvXMLImportContext * CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference< xml::sax::XAttributeList > &rxAttrList );
179 const OUString & GetLeftText() const { return aLeftText; }
180 sal_Int16 GetPropertyType() const { return nPropertyType; }
181 void SetPropertyType( sal_Int16 nVal ) { nPropertyType = nVal; }
185 class ConvDicXMLRightTextContext_Impl :
186 public ConvDicXMLImportContext
188 OUString aRightText;
189 ConvDicXMLEntryTextContext_Impl &rEntryContext;
191 public:
192 ConvDicXMLRightTextContext_Impl(
193 ConvDicXMLImport &rImport,
194 sal_uInt16 nPrefix, const OUString& rLName,
195 ConvDicXMLEntryTextContext_Impl &rParentContext ) :
196 ConvDicXMLImportContext( rImport, nPrefix, rLName ),
197 rEntryContext( rParentContext )
201 // SvXMLImportContext
202 virtual void EndElement();
203 virtual SvXMLImportContext * CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference< xml::sax::XAttributeList > &rxAttrList );
204 virtual void Characters( const OUString &rChars );
206 const OUString & GetRightText() const { return aRightText; }
207 const OUString & GetLeftText() const { return rEntryContext.GetLeftText(); }
208 ConvDic * GetDic() { return GetConvDicImport().GetDic(); }
211 ///////////////////////////////////////////////////////////////////////////
213 void ConvDicXMLImportContext::Characters(const OUString & /*rChars*/)
216 Whitespace occurring within the content of token elements is "trimmed"
217 from the ends (i.e. all whitespace at the beginning and end of the
218 content is removed), and "collapsed" internally (i.e. each sequence of
219 1 or more whitespace characters is replaced with one blank character).
221 //collapsing not done yet!
223 // warning-free code: since the result is not used there is no need for trimming...
224 //const OUString &rChars2 = rChars.trim();
227 SvXMLImportContext * ConvDicXMLImportContext::CreateChildContext(
228 sal_uInt16 nPrefix, const OUString& rLocalName,
229 const uno::Reference< xml::sax::XAttributeList > & /*rxAttrList*/ )
231 SvXMLImportContext *pContext = 0;
232 if (nPrefix == XML_NAMESPACE_TCD && rLocalName.equalsAscii( "text-conversion-dictionary" ))
233 pContext = new ConvDicXMLDictionaryContext_Impl( GetConvDicImport(), nPrefix, rLocalName );
234 else
235 pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
236 return pContext;
239 ////////////////////////////////////////
241 void ConvDicXMLDictionaryContext_Impl::StartElement(
242 const uno::Reference< xml::sax::XAttributeList > &rxAttrList )
244 sal_Int16 nAttrCount = rxAttrList.is() ? rxAttrList->getLength() : 0;
245 for (sal_Int16 i = 0; i < nAttrCount; ++i)
247 OUString aAttrName = rxAttrList->getNameByIndex(i);
248 OUString aLocalName;
249 sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
250 GetKeyByAttrName( aAttrName, &aLocalName );
251 OUString aValue = rxAttrList->getValueByIndex(i);
253 if (nPrefix == XML_NAMESPACE_TCD && aLocalName.equalsAscii( "lang" ))
254 nLanguage = MsLangId::convertIsoStringToLanguage( aValue );
255 else if (nPrefix == XML_NAMESPACE_TCD && aLocalName.equalsAscii( "conversion-type" ))
256 nConversionType = GetConversionTypeFromText( aValue );
258 GetConvDicImport().SetLanguage( nLanguage );
259 GetConvDicImport().SetConversionType( nConversionType );
261 //!! hack to stop the parser from reading the rest of the file !!
262 //!! when only the header (language, conversion type) is needed !!
263 // if (GetConvDicImport().GetDic() == 0)
264 // throw uno::RuntimeException();
267 SvXMLImportContext * ConvDicXMLDictionaryContext_Impl::CreateChildContext(
268 sal_uInt16 nPrefix, const OUString& rLocalName,
269 const uno::Reference< xml::sax::XAttributeList > & /*rxAttrList*/ )
271 SvXMLImportContext *pContext = 0;
272 if (nPrefix == XML_NAMESPACE_TCD && rLocalName.equalsAscii( "entry" ))
273 pContext = new ConvDicXMLEntryTextContext_Impl( GetConvDicImport(), nPrefix, rLocalName, *this );
274 else
275 pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
276 return pContext;
279 ////////////////////////////////////////
281 SvXMLImportContext * ConvDicXMLEntryTextContext_Impl::CreateChildContext(
282 sal_uInt16 nPrefix, const OUString& rLocalName,
283 const uno::Reference< xml::sax::XAttributeList > & /*rxAttrList*/ )
285 SvXMLImportContext *pContext = 0;
286 if (nPrefix == XML_NAMESPACE_TCD && rLocalName.equalsAscii( "right-text" ))
287 pContext = new ConvDicXMLRightTextContext_Impl( GetConvDicImport(), nPrefix, rLocalName, *this );
288 else
289 pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
290 return pContext;
293 void ConvDicXMLEntryTextContext_Impl::StartElement(
294 const uno::Reference< xml::sax::XAttributeList >& rxAttrList )
296 sal_Int16 nAttrCount = rxAttrList.is() ? rxAttrList->getLength() : 0;
297 for (sal_Int16 i = 0; i < nAttrCount; ++i)
299 OUString aAttrName = rxAttrList->getNameByIndex(i);
300 OUString aLocalName;
301 sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
302 GetKeyByAttrName( aAttrName, &aLocalName );
303 OUString aValue = rxAttrList->getValueByIndex(i);
305 if (nPrefix == XML_NAMESPACE_TCD && aLocalName.equalsAscii( "left-text" ))
306 aLeftText = aValue;
307 if (nPrefix == XML_NAMESPACE_TCD && aLocalName.equalsAscii( "property-type" ))
308 nPropertyType = (sal_Int16) aValue.toInt32();
312 ////////////////////////////////////////
314 SvXMLImportContext * ConvDicXMLRightTextContext_Impl::CreateChildContext(
315 sal_uInt16 nPrefix, const OUString& rLocalName,
316 const uno::Reference< xml::sax::XAttributeList > & /*rxAttrList*/ )
318 // leaf: return default (empty) context
319 SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
320 return pContext;
323 void ConvDicXMLRightTextContext_Impl::Characters( const OUString &rChars )
325 aRightText += rChars;
328 void ConvDicXMLRightTextContext_Impl::EndElement()
330 ConvDic *pDic = GetDic();
331 if (pDic)
332 pDic->AddEntry( GetLeftText(), GetRightText() );
336 ///////////////////////////////////////////////////////////////////////////
338 sal_Bool ConvDicXMLExport::Export( SfxMedium & /*rMedium*/ )
340 sal_Bool bRet = sal_False;
342 uno::Reference< document::XExporter > xExporter( this );
343 uno::Reference< document::XFilter > xFilter( xExporter, UNO_QUERY );
344 uno::Sequence< beans::PropertyValue > aProps(0);
345 xFilter->filter( aProps ); // calls exportDoc implicitly
347 return bRet = bSuccess;
351 sal_uInt32 ConvDicXMLExport::exportDoc( enum ::xmloff::token::XMLTokenEnum /*eClass*/ )
353 _GetNamespaceMap().Add( A2OU( "tcd" ),
354 A2OU( XML_NAMESPACE_TCD_STRING ), XML_NAMESPACE_TCD );
356 GetDocHandler()->startDocument();
358 // Add xmlns line and some other arguments
359 AddAttribute( _GetNamespaceMap().GetAttrNameByKey( XML_NAMESPACE_TCD ),
360 _GetNamespaceMap().GetNameByKey( XML_NAMESPACE_TCD ) );
361 AddAttributeASCII( XML_NAMESPACE_TCD, "package", "org.openoffice.Office" );
363 OUString aIsoLang( MsLangId::convertLanguageToIsoString( rDic.nLanguage ) );
364 AddAttribute( XML_NAMESPACE_TCD, "lang", aIsoLang );
365 OUString aConvType( ConversionTypeToText( rDic.nConversionType ) );
366 AddAttribute( XML_NAMESPACE_TCD, "conversion-type", aConvType );
368 //!! block necessary in order to have SvXMLElementExport d-tor called
369 //!! before the call to endDocument
371 SvXMLElementExport aRoot( *this, XML_NAMESPACE_TCD, "text-conversion-dictionary", sal_True, sal_True );
372 _ExportContent();
375 GetDocHandler()->endDocument();
377 bSuccess = sal_True;
378 return 0;
382 void ConvDicXMLExport::_ExportContent()
384 // aquire sorted list of all keys
385 ConvMapKeySet aKeySet;
386 ConvMap::iterator aIt;
387 for (aIt = rDic.aFromLeft.begin(); aIt != rDic.aFromLeft.end(); ++aIt)
388 aKeySet.insert( (*aIt).first );
390 ConvMapKeySet::iterator aKeyIt;
391 for (aKeyIt = aKeySet.begin(); aKeyIt != aKeySet.end(); ++aKeyIt)
393 OUString aLeftText( *aKeyIt );
394 AddAttribute( XML_NAMESPACE_TCD, "left-text", aLeftText );
395 if (rDic.pConvPropType.get()) // property-type list available?
397 sal_Int16 nPropertyType = -1;
398 PropTypeMap::iterator aIt2 = rDic.pConvPropType->find( aLeftText );
399 if (aIt2 != rDic.pConvPropType->end())
400 nPropertyType = (*aIt2).second;
401 DBG_ASSERT( nPropertyType, "property-type not found" );
402 if (nPropertyType == -1)
403 nPropertyType = ConversionPropertyType::NOT_DEFINED;
404 AddAttribute( XML_NAMESPACE_TCD, "property-type", OUString::valueOf( (sal_Int32) nPropertyType ) );
406 SvXMLElementExport aEntryMain( *this, XML_NAMESPACE_TCD,
407 "entry" , sal_True, sal_True );
409 pair< ConvMap::iterator, ConvMap::iterator > aRange =
410 rDic.aFromLeft.equal_range( *aKeyIt );
411 for (aIt = aRange.first; aIt != aRange.second; ++aIt)
413 DBG_ASSERT( *aKeyIt == (*aIt).first, "key <-> entry mismatch" );
414 OUString aRightText( (*aIt).second );
415 SvXMLElementExport aEntryRightText( *this, XML_NAMESPACE_TCD,
416 "right-text" , sal_True, sal_False );
417 Characters( aRightText );
422 ::rtl::OUString SAL_CALL ConvDicXMLExport::getImplementationName()
423 throw( uno::RuntimeException )
425 return A2OU( "com.sun.star.lingu2.ConvDicXMLExport" );
428 ///////////////////////////////////////////////////////////////////////////
430 void SAL_CALL ConvDicXMLImport::startDocument(void)
431 throw( xml::sax::SAXException, uno::RuntimeException )
433 // register namespace at first possible opportunity
434 GetNamespaceMap().Add( A2OU( "tcd" ),
435 A2OU( XML_NAMESPACE_TCD_STRING ), XML_NAMESPACE_TCD );
436 SvXMLImport::startDocument();
439 void SAL_CALL ConvDicXMLImport::endDocument(void)
440 throw( xml::sax::SAXException, uno::RuntimeException )
442 SvXMLImport::endDocument();
445 SvXMLImportContext * ConvDicXMLImport::CreateContext(
446 sal_uInt16 nPrefix,
447 const rtl::OUString &rLocalName,
448 const uno::Reference < xml::sax::XAttributeList > & /*rxAttrList*/ )
450 SvXMLImportContext *pContext = 0;
451 if (nPrefix == XML_NAMESPACE_TCD && rLocalName.equalsAscii( "text-conversion-dictionary" ))
452 pContext = new ConvDicXMLDictionaryContext_Impl( *this, nPrefix, rLocalName );
453 else
454 pContext = new SvXMLImportContext( *this, nPrefix, rLocalName );
455 return pContext;
459 OUString SAL_CALL ConvDicXMLImport::getImplementationName()
460 throw( uno::RuntimeException )
462 return A2OU( "com.sun.star.lingu2.ConvDicXMLImport" );
465 ///////////////////////////////////////////////////////////////////////////