allow to create new database using the wizard again (fdo#62937)
[LibreOffice.git] / linguistic / source / convdicxml.cxx
blobefb73c810460d35287e640a68c47d817a4033a20
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <tools/debug.hxx>
21 #include <tools/string.hxx>
22 #include <i18nlangtag/languagetag.hxx>
23 #include <tools/stream.hxx>
24 #include <osl/mutex.hxx>
25 #include <ucbhelper/content.hxx>
27 #include <cppuhelper/factory.hxx> // helper for factories
28 #include <com/sun/star/linguistic2/XConversionDictionary.hpp>
29 #include <com/sun/star/linguistic2/ConversionDictionaryType.hpp>
30 #include <com/sun/star/linguistic2/ConversionPropertyType.hpp>
31 #include <com/sun/star/util/XFlushable.hpp>
32 #include <com/sun/star/lang/Locale.hpp>
33 #include <com/sun/star/lang/EventObject.hpp>
34 #include <com/sun/star/uno/Reference.h>
35 #include <com/sun/star/registry/XRegistryKey.hpp>
36 #include <com/sun/star/util/XFlushListener.hpp>
37 #include <com/sun/star/io/XActiveDataSource.hpp>
38 #include <com/sun/star/document/XFilter.hpp>
39 #include <com/sun/star/beans/PropertyValue.hpp>
40 #include <xmloff/nmspmap.hxx>
41 #include <xmloff/xmlnmspe.hxx>
42 #include <unotools/streamwrap.hxx>
44 #include "convdic.hxx"
45 #include "convdicxml.hxx"
46 #include "linguistic/misc.hxx"
47 #include "defs.hxx"
49 using namespace std;
50 using namespace utl;
51 using namespace osl;
52 using namespace com::sun::star;
53 using namespace com::sun::star::lang;
54 using namespace com::sun::star::uno;
55 using namespace com::sun::star::linguistic2;
56 using namespace linguistic;
59 #define XML_NAMESPACE_TCD_STRING "http://openoffice.org/2003/text-conversion-dictionary"
60 #define CONV_TYPE_HANGUL_HANJA "Hangul / Hanja"
61 #define CONV_TYPE_SCHINESE_TCHINESE "Chinese simplified / Chinese traditional"
64 static const OUString ConversionTypeToText( sal_Int16 nConversionType )
66 OUString aRes;
67 if (nConversionType == ConversionDictionaryType::HANGUL_HANJA)
68 aRes = CONV_TYPE_HANGUL_HANJA;
69 else if (nConversionType == ConversionDictionaryType::SCHINESE_TCHINESE)
70 aRes = CONV_TYPE_SCHINESE_TCHINESE;
71 return aRes;
74 static sal_Int16 GetConversionTypeFromText( const String &rText )
76 sal_Int16 nRes = -1;
77 if (rText.EqualsAscii( CONV_TYPE_HANGUL_HANJA ))
78 nRes = ConversionDictionaryType::HANGUL_HANJA;
79 else if (rText.EqualsAscii( CONV_TYPE_SCHINESE_TCHINESE ))
80 nRes = ConversionDictionaryType::SCHINESE_TCHINESE;
81 return nRes;
85 class ConvDicXMLImportContext :
86 public SvXMLImportContext
88 public:
89 ConvDicXMLImportContext(
90 ConvDicXMLImport &rImport,
91 sal_uInt16 nPrfx, const OUString& rLName ) :
92 SvXMLImportContext( rImport, nPrfx, rLName )
96 const ConvDicXMLImport & GetConvDicImport() const
98 return (const ConvDicXMLImport &) GetImport();
101 ConvDicXMLImport & GetConvDicImport()
103 return (ConvDicXMLImport &) GetImport();
106 // SvXMLImportContext
107 virtual void Characters( const OUString &rChars );
108 virtual SvXMLImportContext * CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference< xml::sax::XAttributeList > &rxAttrList);
112 class ConvDicXMLDictionaryContext_Impl :
113 public ConvDicXMLImportContext
115 sal_Int16 nLanguage;
116 sal_Int16 nConversionType;
118 public:
119 ConvDicXMLDictionaryContext_Impl( ConvDicXMLImport &rImport,
120 sal_uInt16 nPrefix, const OUString& rLName) :
121 ConvDicXMLImportContext( rImport, nPrefix, rLName )
123 nLanguage = LANGUAGE_NONE;
124 nConversionType = -1;
127 // SvXMLImportContext
128 virtual void StartElement( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList );
129 virtual SvXMLImportContext * CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference< xml::sax::XAttributeList > &rxAttrList );
131 sal_Int16 GetLanguage() const { return nLanguage; }
132 sal_Int16 GetConversionType() const { return nConversionType; }
136 class ConvDicXMLEntryTextContext_Impl :
137 public ConvDicXMLImportContext
139 OUString aLeftText;
140 sal_Int16 nPropertyType; // used for Chinese simplified/traditional conversion
142 public:
143 ConvDicXMLEntryTextContext_Impl(
144 ConvDicXMLImport &rImport,
145 sal_uInt16 nPrefix, const OUString& rLName ) :
146 ConvDicXMLImportContext( rImport, nPrefix, rLName ),
147 nPropertyType( ConversionPropertyType::NOT_DEFINED )
151 // SvXMLImportContext
152 virtual void StartElement( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList );
153 virtual SvXMLImportContext * CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference< xml::sax::XAttributeList > &rxAttrList );
155 const OUString & GetLeftText() const { return aLeftText; }
156 sal_Int16 GetPropertyType() const { return nPropertyType; }
157 void SetPropertyType( sal_Int16 nVal ) { nPropertyType = nVal; }
161 class ConvDicXMLRightTextContext_Impl :
162 public ConvDicXMLImportContext
164 OUString aRightText;
165 ConvDicXMLEntryTextContext_Impl &rEntryContext;
167 public:
168 ConvDicXMLRightTextContext_Impl(
169 ConvDicXMLImport &rImport,
170 sal_uInt16 nPrefix, const OUString& rLName,
171 ConvDicXMLEntryTextContext_Impl &rParentContext ) :
172 ConvDicXMLImportContext( rImport, nPrefix, rLName ),
173 rEntryContext( rParentContext )
177 // SvXMLImportContext
178 virtual void EndElement();
179 virtual SvXMLImportContext * CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference< xml::sax::XAttributeList > &rxAttrList );
180 virtual void Characters( const OUString &rChars );
182 const OUString & GetRightText() const { return aRightText; }
183 const OUString & GetLeftText() const { return rEntryContext.GetLeftText(); }
184 ConvDic * GetDic() { return GetConvDicImport().GetDic(); }
188 void ConvDicXMLImportContext::Characters(const OUString & /*rChars*/)
191 Whitespace occurring within the content of token elements is "trimmed"
192 from the ends (i.e. all whitespace at the beginning and end of the
193 content is removed), and "collapsed" internally (i.e. each sequence of
194 1 or more whitespace characters is replaced with one blank character).
196 //collapsing not done yet!
200 SvXMLImportContext * ConvDicXMLImportContext::CreateChildContext(
201 sal_uInt16 nPrefix, const OUString& rLocalName,
202 const uno::Reference< xml::sax::XAttributeList > & /*rxAttrList*/ )
204 SvXMLImportContext *pContext = 0;
205 if ( nPrefix == XML_NAMESPACE_TCD && rLocalName == "text-conversion-dictionary" )
206 pContext = new ConvDicXMLDictionaryContext_Impl( GetConvDicImport(), nPrefix, rLocalName );
207 else
208 pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
209 return pContext;
213 void ConvDicXMLDictionaryContext_Impl::StartElement(
214 const uno::Reference< xml::sax::XAttributeList > &rxAttrList )
216 sal_Int16 nAttrCount = rxAttrList.is() ? rxAttrList->getLength() : 0;
217 for (sal_Int16 i = 0; i < nAttrCount; ++i)
219 OUString aAttrName = rxAttrList->getNameByIndex(i);
220 OUString aLocalName;
221 sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
222 GetKeyByAttrName( aAttrName, &aLocalName );
223 OUString aValue = rxAttrList->getValueByIndex(i);
225 if ( nPrefix == XML_NAMESPACE_TCD && aLocalName == "lang" )
226 nLanguage = LanguageTag( aValue ).getLanguageType();
227 else if ( nPrefix == XML_NAMESPACE_TCD && aLocalName == "conversion-type" )
228 nConversionType = GetConversionTypeFromText( aValue );
230 GetConvDicImport().SetLanguage( nLanguage );
231 GetConvDicImport().SetConversionType( nConversionType );
235 SvXMLImportContext * ConvDicXMLDictionaryContext_Impl::CreateChildContext(
236 sal_uInt16 nPrefix, const OUString& rLocalName,
237 const uno::Reference< xml::sax::XAttributeList > & /*rxAttrList*/ )
239 SvXMLImportContext *pContext = 0;
240 if ( nPrefix == XML_NAMESPACE_TCD && rLocalName == "entry" )
241 pContext = new ConvDicXMLEntryTextContext_Impl( GetConvDicImport(), nPrefix, rLocalName );
242 else
243 pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
244 return pContext;
248 SvXMLImportContext * ConvDicXMLEntryTextContext_Impl::CreateChildContext(
249 sal_uInt16 nPrefix, const OUString& rLocalName,
250 const uno::Reference< xml::sax::XAttributeList > & /*rxAttrList*/ )
252 SvXMLImportContext *pContext = 0;
253 if ( nPrefix == XML_NAMESPACE_TCD && rLocalName == "right-text" )
254 pContext = new ConvDicXMLRightTextContext_Impl( GetConvDicImport(), nPrefix, rLocalName, *this );
255 else
256 pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
257 return pContext;
260 void ConvDicXMLEntryTextContext_Impl::StartElement(
261 const uno::Reference< xml::sax::XAttributeList >& rxAttrList )
263 sal_Int16 nAttrCount = rxAttrList.is() ? rxAttrList->getLength() : 0;
264 for (sal_Int16 i = 0; i < nAttrCount; ++i)
266 OUString aAttrName = rxAttrList->getNameByIndex(i);
267 OUString aLocalName;
268 sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
269 GetKeyByAttrName( aAttrName, &aLocalName );
270 OUString aValue = rxAttrList->getValueByIndex(i);
272 if ( nPrefix == XML_NAMESPACE_TCD && aLocalName == "left-text" )
273 aLeftText = aValue;
274 if ( nPrefix == XML_NAMESPACE_TCD && aLocalName == "property-type" )
275 nPropertyType = (sal_Int16) aValue.toInt32();
280 SvXMLImportContext * ConvDicXMLRightTextContext_Impl::CreateChildContext(
281 sal_uInt16 nPrefix, const OUString& rLocalName,
282 const uno::Reference< xml::sax::XAttributeList > & /*rxAttrList*/ )
284 // leaf: return default (empty) context
285 SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
286 return pContext;
289 void ConvDicXMLRightTextContext_Impl::Characters( const OUString &rChars )
291 aRightText += rChars;
294 void ConvDicXMLRightTextContext_Impl::EndElement()
296 ConvDic *pDic = GetDic();
297 if (pDic)
298 pDic->AddEntry( GetLeftText(), GetRightText() );
303 sal_Bool ConvDicXMLExport::Export()
305 sal_Bool bRet = sal_False;
307 uno::Reference< document::XExporter > xExporter( this );
308 uno::Reference< document::XFilter > xFilter( xExporter, UNO_QUERY );
309 uno::Sequence< beans::PropertyValue > aProps(0);
310 xFilter->filter( aProps ); // calls exportDoc implicitly
312 return bRet = bSuccess;
316 sal_uInt32 ConvDicXMLExport::exportDoc( enum ::xmloff::token::XMLTokenEnum /*eClass*/ )
318 _GetNamespaceMap().Add( "tcd",
319 XML_NAMESPACE_TCD_STRING, XML_NAMESPACE_TCD );
321 GetDocHandler()->startDocument();
323 // Add xmlns line and some other arguments
324 AddAttribute( _GetNamespaceMap().GetAttrNameByKey( XML_NAMESPACE_TCD ),
325 _GetNamespaceMap().GetNameByKey( XML_NAMESPACE_TCD ) );
326 AddAttributeASCII( XML_NAMESPACE_TCD, "package", "org.openoffice.Office" );
328 OUString aIsoLang( LanguageTag( rDic.nLanguage ).getBcp47() );
329 AddAttribute( XML_NAMESPACE_TCD, "lang", aIsoLang );
330 OUString aConvType( ConversionTypeToText( rDic.nConversionType ) );
331 AddAttribute( XML_NAMESPACE_TCD, "conversion-type", aConvType );
333 //!! block necessary in order to have SvXMLElementExport d-tor called
334 //!! before the call to endDocument
336 SvXMLElementExport aRoot( *this, XML_NAMESPACE_TCD, "text-conversion-dictionary", sal_True, sal_True );
337 _ExportContent();
340 GetDocHandler()->endDocument();
342 bSuccess = sal_True;
343 return 0;
347 void ConvDicXMLExport::_ExportContent()
349 // aquire sorted list of all keys
350 ConvMapKeySet aKeySet;
351 ConvMap::iterator aIt;
352 for (aIt = rDic.aFromLeft.begin(); aIt != rDic.aFromLeft.end(); ++aIt)
353 aKeySet.insert( (*aIt).first );
355 ConvMapKeySet::iterator aKeyIt;
356 for (aKeyIt = aKeySet.begin(); aKeyIt != aKeySet.end(); ++aKeyIt)
358 OUString aLeftText( *aKeyIt );
359 AddAttribute( XML_NAMESPACE_TCD, "left-text", aLeftText );
360 if (rDic.pConvPropType.get()) // property-type list available?
362 sal_Int16 nPropertyType = -1;
363 PropTypeMap::iterator aIt2 = rDic.pConvPropType->find( aLeftText );
364 if (aIt2 != rDic.pConvPropType->end())
365 nPropertyType = (*aIt2).second;
366 DBG_ASSERT( nPropertyType, "property-type not found" );
367 if (nPropertyType == -1)
368 nPropertyType = ConversionPropertyType::NOT_DEFINED;
369 AddAttribute( XML_NAMESPACE_TCD, "property-type", OUString::valueOf( (sal_Int32) nPropertyType ) );
371 SvXMLElementExport aEntryMain( *this, XML_NAMESPACE_TCD,
372 "entry" , sal_True, sal_True );
374 pair< ConvMap::iterator, ConvMap::iterator > aRange =
375 rDic.aFromLeft.equal_range( *aKeyIt );
376 for (aIt = aRange.first; aIt != aRange.second; ++aIt)
378 DBG_ASSERT( *aKeyIt == (*aIt).first, "key <-> entry mismatch" );
379 OUString aRightText( (*aIt).second );
380 SvXMLElementExport aEntryRightText( *this, XML_NAMESPACE_TCD,
381 "right-text" , sal_True, sal_False );
382 Characters( aRightText );
387 OUString SAL_CALL ConvDicXMLExport::getImplementationName()
388 throw( uno::RuntimeException )
390 return OUString( "com.sun.star.lingu2.ConvDicXMLExport" );
394 void SAL_CALL ConvDicXMLImport::startDocument(void)
395 throw( xml::sax::SAXException, uno::RuntimeException )
397 // register namespace at first possible opportunity
398 GetNamespaceMap().Add( "tcd",
399 XML_NAMESPACE_TCD_STRING, XML_NAMESPACE_TCD );
400 SvXMLImport::startDocument();
403 void SAL_CALL ConvDicXMLImport::endDocument(void)
404 throw( xml::sax::SAXException, uno::RuntimeException )
406 SvXMLImport::endDocument();
409 SvXMLImportContext * ConvDicXMLImport::CreateContext(
410 sal_uInt16 nPrefix,
411 const OUString &rLocalName,
412 const uno::Reference < xml::sax::XAttributeList > & /*rxAttrList*/ )
414 SvXMLImportContext *pContext = 0;
415 if ( nPrefix == XML_NAMESPACE_TCD && rLocalName == "text-conversion-dictionary" )
416 pContext = new ConvDicXMLDictionaryContext_Impl( *this, nPrefix, rLocalName );
417 else
418 pContext = new SvXMLImportContext( *this, nPrefix, rLocalName );
419 return pContext;
423 OUString SAL_CALL ConvDicXMLImport::getImplementationName()
424 throw( uno::RuntimeException )
426 return OUString( "com.sun.star.lingu2.ConvDicXMLImport" );
430 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */