bump product version to 7.2.5.1
[LibreOffice.git] / linguistic / source / convdicxml.cxx
blob3549060acfebf98ad0fafbc4458a7b4f281987b7
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 <i18nlangtag/languagetag.hxx>
23 #include <com/sun/star/linguistic2/ConversionDictionaryType.hpp>
24 #include <com/sun/star/linguistic2/ConversionPropertyType.hpp>
25 #include <com/sun/star/lang/Locale.hpp>
26 #include <com/sun/star/uno/Reference.h>
27 #include <com/sun/star/document/XFilter.hpp>
28 #include <com/sun/star/beans/PropertyValue.hpp>
29 #include <xmloff/namespacemap.hxx>
30 #include <xmloff/xmlnamespace.hxx>
31 #include <unotools/streamwrap.hxx>
33 #include "convdic.hxx"
34 #include "convdicxml.hxx"
35 #include <linguistic/misc.hxx>
37 using namespace std;
38 using namespace utl;
39 using namespace com::sun::star;
40 using namespace com::sun::star::lang;
41 using namespace com::sun::star::uno;
42 using namespace com::sun::star::linguistic2;
43 using namespace linguistic;
46 #define XML_NAMESPACE_TCD_STRING "http://openoffice.org/2003/text-conversion-dictionary"
47 #define CONV_TYPE_HANGUL_HANJA u"Hangul / Hanja"
48 #define CONV_TYPE_SCHINESE_TCHINESE u"Chinese simplified / Chinese traditional"
51 static OUString ConversionTypeToText( sal_Int16 nConversionType )
53 OUString aRes;
54 if (nConversionType == ConversionDictionaryType::HANGUL_HANJA)
55 aRes = CONV_TYPE_HANGUL_HANJA;
56 else if (nConversionType == ConversionDictionaryType::SCHINESE_TCHINESE)
57 aRes = CONV_TYPE_SCHINESE_TCHINESE;
58 return aRes;
61 static sal_Int16 GetConversionTypeFromText( std::u16string_view rText )
63 sal_Int16 nRes = -1;
64 if (rText == CONV_TYPE_HANGUL_HANJA)
65 nRes = ConversionDictionaryType::HANGUL_HANJA;
66 else if (rText == CONV_TYPE_SCHINESE_TCHINESE)
67 nRes = ConversionDictionaryType::SCHINESE_TCHINESE;
68 return nRes;
71 namespace {
73 class ConvDicXMLImportContext :
74 public SvXMLImportContext
76 public:
77 ConvDicXMLImportContext( ConvDicXMLImport &rImport ) :
78 SvXMLImportContext( rImport )
82 ConvDicXMLImport & GetConvDicImport()
84 return static_cast<ConvDicXMLImport &>(GetImport());
87 // SvXMLImportContext
88 virtual css::uno::Reference<XFastContextHandler> SAL_CALL createFastChildContext(
89 sal_Int32 Element, const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList ) override;
93 class ConvDicXMLDictionaryContext_Impl :
94 public ConvDicXMLImportContext
96 LanguageType nLanguage;
97 sal_Int16 nConversionType;
99 public:
100 ConvDicXMLDictionaryContext_Impl( ConvDicXMLImport &rImport ) :
101 ConvDicXMLImportContext( rImport ),
102 nLanguage(LANGUAGE_NONE), nConversionType(-1)
106 // SvXMLImportContext
107 virtual void SAL_CALL startFastElement( sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& Attribs ) override;
108 virtual css::uno::Reference<XFastContextHandler> SAL_CALL createFastChildContext(
109 sal_Int32 Element, const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList ) override;
113 class ConvDicXMLEntryTextContext_Impl :
114 public ConvDicXMLImportContext
116 OUString aLeftText;
118 public:
119 ConvDicXMLEntryTextContext_Impl( ConvDicXMLImport &rImport ) :
120 ConvDicXMLImportContext( rImport )
124 // SvXMLImportContext
125 virtual void SAL_CALL startFastElement( sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& Attribs ) override;
126 virtual css::uno::Reference<XFastContextHandler> SAL_CALL createFastChildContext(
127 sal_Int32 Element, const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList ) override;
129 const OUString & GetLeftText() const { return aLeftText; }
133 class ConvDicXMLRightTextContext_Impl :
134 public ConvDicXMLImportContext
136 OUString aRightText;
137 ConvDicXMLEntryTextContext_Impl &rEntryContext;
139 public:
140 ConvDicXMLRightTextContext_Impl(
141 ConvDicXMLImport &rImport,
142 ConvDicXMLEntryTextContext_Impl &rParentContext ) :
143 ConvDicXMLImportContext( rImport ),
144 rEntryContext( rParentContext )
148 // SvXMLImportContext
149 virtual void SAL_CALL endFastElement( sal_Int32 nElement ) override;
150 virtual void SAL_CALL characters( const OUString &rChars ) override;
155 //void ConvDicXMLImportContext::characters(const OUString & /*rChars*/)
158 Whitespace occurring within the content of token elements is "trimmed"
159 from the ends (i.e. all whitespace at the beginning and end of the
160 content is removed), and "collapsed" internally (i.e. each sequence of
161 1 or more whitespace characters is replaced with one blank character).
163 //collapsing not done yet!
167 css::uno::Reference<XFastContextHandler> ConvDicXMLImportContext::createFastChildContext(
168 sal_Int32 Element,
169 const css::uno::Reference< css::xml::sax::XFastAttributeList > & /*xAttrList*/ )
171 if ( Element == ConvDicXMLToken::TEXT_CONVERSION_DICTIONARY )
172 return new ConvDicXMLDictionaryContext_Impl( GetConvDicImport() );
173 return nullptr;
177 void ConvDicXMLDictionaryContext_Impl::startFastElement( sal_Int32 /*nElement*/,
178 const css::uno::Reference< css::xml::sax::XFastAttributeList >& rxAttrList )
180 for (auto &aIter : sax_fastparser::castToFastAttributeList( rxAttrList ))
182 switch (aIter.getToken())
184 case XML_NAMESPACE_TCD | XML_LANG:
185 nLanguage = LanguageTag::convertToLanguageType( aIter.toString() );
186 break;
187 case XML_NAMESPACE_TCD | XML_CONVERSION_TYPE:
188 nConversionType = GetConversionTypeFromText( aIter.toString() );
189 break;
190 default:
194 GetConvDicImport().SetLanguage( nLanguage );
195 GetConvDicImport().SetConversionType( nConversionType );
199 css::uno::Reference<XFastContextHandler> ConvDicXMLDictionaryContext_Impl::createFastChildContext(
200 sal_Int32 Element,
201 const css::uno::Reference< css::xml::sax::XFastAttributeList > & /*xAttrList*/ )
203 if ( Element == ConvDicXMLToken::ENTRY )
204 return new ConvDicXMLEntryTextContext_Impl( GetConvDicImport() );
205 return nullptr;
208 css::uno::Reference<XFastContextHandler> ConvDicXMLEntryTextContext_Impl::createFastChildContext(
209 sal_Int32 Element,
210 const css::uno::Reference< css::xml::sax::XFastAttributeList > & /*xAttrList*/ )
212 if ( Element == ConvDicXMLToken::RIGHT_TEXT )
213 return new ConvDicXMLRightTextContext_Impl( GetConvDicImport(), *this );
214 return nullptr;
217 void ConvDicXMLEntryTextContext_Impl::startFastElement(
218 sal_Int32 /*Element*/,
219 const css::uno::Reference< css::xml::sax::XFastAttributeList >& rxAttrList )
221 for (auto &aIter : sax_fastparser::castToFastAttributeList( rxAttrList ))
223 switch (aIter.getToken())
225 case XML_NAMESPACE_TCD | XML_LEFT_TEXT:
226 aLeftText = aIter.toString();
227 break;
228 default:
235 void ConvDicXMLRightTextContext_Impl::characters( const OUString &rChars )
237 aRightText += rChars;
240 void ConvDicXMLRightTextContext_Impl::endFastElement( sal_Int32 /*nElement*/ )
242 ConvDic *pDic = GetConvDicImport().GetDic();
243 if (pDic)
244 pDic->AddEntry( rEntryContext.GetLeftText(), aRightText );
248 bool ConvDicXMLExport::Export()
250 uno::Reference< document::XExporter > xExporter( this );
251 uno::Reference< document::XFilter > xFilter( xExporter, UNO_QUERY );
252 uno::Sequence< beans::PropertyValue > aProps(0);
253 xFilter->filter( aProps ); // calls exportDoc implicitly
255 return bSuccess;
259 ErrCode ConvDicXMLExport::exportDoc( enum ::xmloff::token::XMLTokenEnum /*eClass*/ )
261 GetNamespaceMap_().Add( "tcd",
262 XML_NAMESPACE_TCD_STRING, XML_NAMESPACE_TCD );
264 GetDocHandler()->startDocument();
266 // Add xmlns line and some other arguments
267 AddAttribute( GetNamespaceMap_().GetAttrNameByKey( XML_NAMESPACE_TCD ),
268 GetNamespaceMap_().GetNameByKey( XML_NAMESPACE_TCD ) );
269 AddAttributeASCII( XML_NAMESPACE_TCD, "package", "org.openoffice.Office" );
271 OUString aIsoLang( LanguageTag::convertToBcp47( rDic.nLanguage ) );
272 AddAttribute( XML_NAMESPACE_TCD, "lang", aIsoLang );
273 OUString aConvType( ConversionTypeToText( rDic.nConversionType ) );
274 AddAttribute( XML_NAMESPACE_TCD, "conversion-type", aConvType );
276 //!! block necessary in order to have SvXMLElementExport d-tor called
277 //!! before the call to endDocument
279 SvXMLElementExport aRoot( *this, XML_NAMESPACE_TCD, "text-conversion-dictionary", true, true );
280 ExportContent_();
283 GetDocHandler()->endDocument();
285 bSuccess = true;
286 return ERRCODE_NONE;
290 void ConvDicXMLExport::ExportContent_()
292 // acquire sorted list of all keys
293 std::set<OUString> aKeySet;
294 for (auto const& elem : rDic.aFromLeft)
295 aKeySet.insert( elem.first );
297 for (const OUString& aLeftText : aKeySet)
299 AddAttribute( XML_NAMESPACE_TCD, "left-text", aLeftText );
300 if (rDic.pConvPropType) // property-type list available?
302 sal_Int16 nPropertyType = -1;
303 PropTypeMap::iterator aIt2 = rDic.pConvPropType->find( aLeftText );
304 if (aIt2 != rDic.pConvPropType->end())
305 nPropertyType = (*aIt2).second;
306 DBG_ASSERT( nPropertyType, "property-type not found" );
307 if (nPropertyType == -1)
308 nPropertyType = ConversionPropertyType::NOT_DEFINED;
309 AddAttribute( XML_NAMESPACE_TCD, "property-type", OUString::number( nPropertyType ) );
311 SvXMLElementExport aEntryMain( *this, XML_NAMESPACE_TCD,
312 "entry" , true, true );
314 pair< ConvMap::iterator, ConvMap::iterator > aRange =
315 rDic.aFromLeft.equal_range(aLeftText);
316 for (auto aIt = aRange.first; aIt != aRange.second; ++aIt)
318 DBG_ASSERT( aLeftText == (*aIt).first, "key <-> entry mismatch" );
319 OUString aRightText( (*aIt).second );
320 SvXMLElementExport aEntryRightText( *this, XML_NAMESPACE_TCD,
321 "right-text" , true, false );
322 Characters( aRightText );
327 //!! see comment for pDic member
328 ConvDicXMLImport::ConvDicXMLImport( ConvDic *pConvDic ) :
329 SvXMLImport ( comphelper::getProcessComponentContext(), "com.sun.star.lingu2.ConvDicXMLImport", SvXMLImportFlags::ALL ),
330 pDic ( pConvDic ), nLanguage(LANGUAGE_NONE), nConversionType(-1)
332 GetNamespaceMap().Add( GetXMLToken(XML_NP_TCD), GetXMLToken(XML_N_TCD), XML_NAMESPACE_TCD);
335 SvXMLImportContext * ConvDicXMLImport::CreateFastContext(
336 sal_Int32 Element,
337 const css::uno::Reference< css::xml::sax::XFastAttributeList > & /*xAttrList*/ )
339 if( Element == ConvDicXMLToken::TEXT_CONVERSION_DICTIONARY )
340 return new ConvDicXMLDictionaryContext_Impl( *this );
341 return nullptr;
344 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */