Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / linguistic / source / convdicxml.cxx
blobc8a09997fd7e9fc3952753613ca9e8a615d652e0
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 utl;
38 using namespace com::sun::star;
39 using namespace com::sun::star::lang;
40 using namespace com::sun::star::uno;
41 using namespace com::sun::star::linguistic2;
42 using namespace linguistic;
45 constexpr OUStringLiteral XML_NAMESPACE_TCD_STRING = u"http://openoffice.org/2003/text-conversion-dictionary";
46 constexpr OUStringLiteral CONV_TYPE_HANGUL_HANJA = u"Hangul / Hanja";
47 constexpr OUStringLiteral CONV_TYPE_SCHINESE_TCHINESE = u"Chinese simplified / Chinese traditional";
50 static OUString ConversionTypeToText( sal_Int16 nConversionType )
52 OUString aRes;
53 if (nConversionType == ConversionDictionaryType::HANGUL_HANJA)
54 aRes = CONV_TYPE_HANGUL_HANJA;
55 else if (nConversionType == ConversionDictionaryType::SCHINESE_TCHINESE)
56 aRes = CONV_TYPE_SCHINESE_TCHINESE;
57 return aRes;
60 static sal_Int16 GetConversionTypeFromText( std::u16string_view rText )
62 sal_Int16 nRes = -1;
63 if (rText == CONV_TYPE_HANGUL_HANJA)
64 nRes = ConversionDictionaryType::HANGUL_HANJA;
65 else if (rText == CONV_TYPE_SCHINESE_TCHINESE)
66 nRes = ConversionDictionaryType::SCHINESE_TCHINESE;
67 return nRes;
70 namespace {
72 class ConvDicXMLImportContext :
73 public SvXMLImportContext
75 public:
76 ConvDicXMLImportContext( ConvDicXMLImport &rImport ) :
77 SvXMLImportContext( rImport )
81 ConvDicXMLImport & GetConvDicImport()
83 return static_cast<ConvDicXMLImport &>(GetImport());
86 // SvXMLImportContext
87 virtual css::uno::Reference<XFastContextHandler> SAL_CALL createFastChildContext(
88 sal_Int32 Element, const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList ) override;
92 class ConvDicXMLDictionaryContext_Impl :
93 public ConvDicXMLImportContext
95 LanguageType nLanguage;
96 sal_Int16 nConversionType;
98 public:
99 ConvDicXMLDictionaryContext_Impl( ConvDicXMLImport &rImport ) :
100 ConvDicXMLImportContext( rImport ),
101 nLanguage(LANGUAGE_NONE), nConversionType(-1)
105 // SvXMLImportContext
106 virtual void SAL_CALL startFastElement( sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& Attribs ) override;
107 virtual css::uno::Reference<XFastContextHandler> SAL_CALL createFastChildContext(
108 sal_Int32 Element, const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList ) override;
112 class ConvDicXMLEntryTextContext_Impl :
113 public ConvDicXMLImportContext
115 OUString aLeftText;
117 public:
118 ConvDicXMLEntryTextContext_Impl( ConvDicXMLImport &rImport ) :
119 ConvDicXMLImportContext( rImport )
123 // SvXMLImportContext
124 virtual void SAL_CALL startFastElement( sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& Attribs ) override;
125 virtual css::uno::Reference<XFastContextHandler> SAL_CALL createFastChildContext(
126 sal_Int32 Element, const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList ) override;
128 const OUString & GetLeftText() const { return aLeftText; }
132 class ConvDicXMLRightTextContext_Impl :
133 public ConvDicXMLImportContext
135 OUString aRightText;
136 ConvDicXMLEntryTextContext_Impl &rEntryContext;
138 public:
139 ConvDicXMLRightTextContext_Impl(
140 ConvDicXMLImport &rImport,
141 ConvDicXMLEntryTextContext_Impl &rParentContext ) :
142 ConvDicXMLImportContext( rImport ),
143 rEntryContext( rParentContext )
147 // SvXMLImportContext
148 virtual void SAL_CALL endFastElement( sal_Int32 nElement ) override;
149 virtual void SAL_CALL characters( const OUString &rChars ) override;
154 //void ConvDicXMLImportContext::characters(const OUString & /*rChars*/)
157 Whitespace occurring within the content of token elements is "trimmed"
158 from the ends (i.e. all whitespace at the beginning and end of the
159 content is removed), and "collapsed" internally (i.e. each sequence of
160 1 or more whitespace characters is replaced with one blank character).
162 //collapsing not done yet!
166 css::uno::Reference<XFastContextHandler> ConvDicXMLImportContext::createFastChildContext(
167 sal_Int32 Element,
168 const css::uno::Reference< css::xml::sax::XFastAttributeList > & /*xAttrList*/ )
170 if ( Element == ConvDicXMLToken::TEXT_CONVERSION_DICTIONARY )
171 return new ConvDicXMLDictionaryContext_Impl( GetConvDicImport() );
172 return nullptr;
176 void ConvDicXMLDictionaryContext_Impl::startFastElement( sal_Int32 /*nElement*/,
177 const css::uno::Reference< css::xml::sax::XFastAttributeList >& rxAttrList )
179 for (auto &aIter : sax_fastparser::castToFastAttributeList( rxAttrList ))
181 switch (aIter.getToken())
183 case XML_NAMESPACE_TCD | XML_LANG:
184 nLanguage = LanguageTag::convertToLanguageType( aIter.toString() );
185 break;
186 case XML_NAMESPACE_TCD | XML_CONVERSION_TYPE:
187 nConversionType = GetConversionTypeFromText( aIter.toString() );
188 break;
189 default:
193 GetConvDicImport().SetLanguage( nLanguage );
194 GetConvDicImport().SetConversionType( nConversionType );
198 css::uno::Reference<XFastContextHandler> ConvDicXMLDictionaryContext_Impl::createFastChildContext(
199 sal_Int32 Element,
200 const css::uno::Reference< css::xml::sax::XFastAttributeList > & /*xAttrList*/ )
202 if ( Element == ConvDicXMLToken::ENTRY )
203 return new ConvDicXMLEntryTextContext_Impl( GetConvDicImport() );
204 return nullptr;
207 css::uno::Reference<XFastContextHandler> ConvDicXMLEntryTextContext_Impl::createFastChildContext(
208 sal_Int32 Element,
209 const css::uno::Reference< css::xml::sax::XFastAttributeList > & /*xAttrList*/ )
211 if ( Element == ConvDicXMLToken::RIGHT_TEXT )
212 return new ConvDicXMLRightTextContext_Impl( GetConvDicImport(), *this );
213 return nullptr;
216 void ConvDicXMLEntryTextContext_Impl::startFastElement(
217 sal_Int32 /*Element*/,
218 const css::uno::Reference< css::xml::sax::XFastAttributeList >& rxAttrList )
220 for (auto &aIter : sax_fastparser::castToFastAttributeList( rxAttrList ))
222 switch (aIter.getToken())
224 case XML_NAMESPACE_TCD | XML_LEFT_TEXT:
225 aLeftText = aIter.toString();
226 break;
227 default:
234 void ConvDicXMLRightTextContext_Impl::characters( const OUString &rChars )
236 aRightText += rChars;
239 void ConvDicXMLRightTextContext_Impl::endFastElement( sal_Int32 /*nElement*/ )
241 ConvDic *pDic = GetConvDicImport().GetDic();
242 if (pDic)
243 pDic->AddEntry( rEntryContext.GetLeftText(), aRightText );
247 bool ConvDicXMLExport::Export()
249 uno::Reference< document::XExporter > xExporter( this );
250 uno::Reference< document::XFilter > xFilter( xExporter, UNO_QUERY );
251 xFilter->filter( {} ); // calls exportDoc implicitly
253 return bSuccess;
257 ErrCode ConvDicXMLExport::exportDoc( enum ::xmloff::token::XMLTokenEnum /*eClass*/ )
259 GetNamespaceMap_().Add( "tcd",
260 XML_NAMESPACE_TCD_STRING, XML_NAMESPACE_TCD );
262 GetDocHandler()->startDocument();
264 // Add xmlns line and some other arguments
265 AddAttribute( GetNamespaceMap_().GetAttrNameByKey( XML_NAMESPACE_TCD ),
266 GetNamespaceMap_().GetNameByKey( XML_NAMESPACE_TCD ) );
267 AddAttribute( XML_NAMESPACE_TCD, "package", "org.openoffice.Office" );
269 OUString aIsoLang( LanguageTag::convertToBcp47( rDic.nLanguage ) );
270 AddAttribute( XML_NAMESPACE_TCD, "lang", aIsoLang );
271 OUString aConvType( ConversionTypeToText( rDic.nConversionType ) );
272 AddAttribute( XML_NAMESPACE_TCD, "conversion-type", aConvType );
274 //!! block necessary in order to have SvXMLElementExport d-tor called
275 //!! before the call to endDocument
277 SvXMLElementExport aRoot( *this, XML_NAMESPACE_TCD, "text-conversion-dictionary", true, true );
278 ExportContent_();
281 GetDocHandler()->endDocument();
283 bSuccess = true;
284 return ERRCODE_NONE;
288 void ConvDicXMLExport::ExportContent_()
290 // acquire sorted list of all keys
291 std::set<OUString> aKeySet;
292 for (auto const& elem : rDic.aFromLeft)
293 aKeySet.insert( elem.first );
295 for (const OUString& aLeftText : aKeySet)
297 AddAttribute( XML_NAMESPACE_TCD, "left-text", aLeftText );
298 if (rDic.pConvPropType) // property-type list available?
300 sal_Int16 nPropertyType = -1;
301 PropTypeMap::iterator aIt2 = rDic.pConvPropType->find( aLeftText );
302 if (aIt2 != rDic.pConvPropType->end())
303 nPropertyType = (*aIt2).second;
304 DBG_ASSERT( nPropertyType, "property-type not found" );
305 if (nPropertyType == -1)
306 nPropertyType = ConversionPropertyType::NOT_DEFINED;
307 AddAttribute( XML_NAMESPACE_TCD, "property-type", OUString::number( nPropertyType ) );
309 SvXMLElementExport aEntryMain( *this, XML_NAMESPACE_TCD,
310 "entry" , true, true );
312 std::pair< ConvMap::iterator, ConvMap::iterator > aRange =
313 rDic.aFromLeft.equal_range(aLeftText);
314 for (auto aIt = aRange.first; aIt != aRange.second; ++aIt)
316 DBG_ASSERT( aLeftText == (*aIt).first, "key <-> entry mismatch" );
317 OUString aRightText( (*aIt).second );
318 SvXMLElementExport aEntryRightText( *this, XML_NAMESPACE_TCD,
319 "right-text" , true, false );
320 Characters( aRightText );
325 //!! see comment for pDic member
326 ConvDicXMLImport::ConvDicXMLImport( ConvDic *pConvDic ) :
327 SvXMLImport ( comphelper::getProcessComponentContext(), "com.sun.star.lingu2.ConvDicXMLImport", SvXMLImportFlags::ALL ),
328 pDic ( pConvDic ), nLanguage(LANGUAGE_NONE), nConversionType(-1)
330 GetNamespaceMap().Add( GetXMLToken(XML_NP_TCD), GetXMLToken(XML_N_TCD), XML_NAMESPACE_TCD);
333 SvXMLImportContext * ConvDicXMLImport::CreateFastContext(
334 sal_Int32 Element,
335 const css::uno::Reference< css::xml::sax::XFastAttributeList > & /*xAttrList*/ )
337 if( Element == ConvDicXMLToken::TEXT_CONVERSION_DICTIONARY )
338 return new ConvDicXMLDictionaryContext_Impl( *this );
339 return nullptr;
342 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */