LibreOffice Module linguistic (master) 1
convdicxml.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <tools/debug.hxx>
22
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>
32
33#include "convdic.hxx"
34#include "convdicxml.hxx"
35#include <linguistic/misc.hxx>
36
37using namespace utl;
38using namespace com::sun::star;
39using namespace com::sun::star::lang;
40using namespace com::sun::star::uno;
41using namespace com::sun::star::linguistic2;
42using namespace linguistic;
43
44
45constexpr OUStringLiteral XML_NAMESPACE_TCD_STRING = u"http://openoffice.org/2003/text-conversion-dictionary";
46constexpr OUStringLiteral CONV_TYPE_HANGUL_HANJA = u"Hangul / Hanja";
47constexpr OUStringLiteral CONV_TYPE_SCHINESE_TCHINESE = u"Chinese simplified / Chinese traditional";
48
49
50static OUString ConversionTypeToText( sal_Int16 nConversionType )
51{
52 OUString aRes;
53 if (nConversionType == ConversionDictionaryType::HANGUL_HANJA)
55 else if (nConversionType == ConversionDictionaryType::SCHINESE_TCHINESE)
57 return aRes;
58}
59
60static sal_Int16 GetConversionTypeFromText( std::u16string_view rText )
61{
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;
68}
69
70namespace {
71
72class ConvDicXMLImportContext :
74{
75public:
76 ConvDicXMLImportContext( ConvDicXMLImport &rImport ) :
77 SvXMLImportContext( rImport )
78 {
79 }
80
81 ConvDicXMLImport & GetConvDicImport()
82 {
83 return static_cast<ConvDicXMLImport &>(GetImport());
84 }
85
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;
89};
90
91
92class ConvDicXMLDictionaryContext_Impl :
93 public ConvDicXMLImportContext
94{
95 LanguageType nLanguage;
96 sal_Int16 nConversionType;
97
98public:
99 ConvDicXMLDictionaryContext_Impl( ConvDicXMLImport &rImport ) :
100 ConvDicXMLImportContext( rImport ),
101 nLanguage(LANGUAGE_NONE), nConversionType(-1)
102 {
103 }
104
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;
109};
110
111
112class ConvDicXMLEntryTextContext_Impl :
113 public ConvDicXMLImportContext
114{
115 OUString aLeftText;
116
117public:
118 ConvDicXMLEntryTextContext_Impl( ConvDicXMLImport &rImport ) :
119 ConvDicXMLImportContext( rImport )
120 {
121 }
122
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;
127
128 const OUString & GetLeftText() const { return aLeftText; }
129};
130
131
132class ConvDicXMLRightTextContext_Impl :
133 public ConvDicXMLImportContext
134{
135 OUString aRightText;
136 ConvDicXMLEntryTextContext_Impl &rEntryContext;
137
138public:
139 ConvDicXMLRightTextContext_Impl(
140 ConvDicXMLImport &rImport,
141 ConvDicXMLEntryTextContext_Impl &rParentContext ) :
142 ConvDicXMLImportContext( rImport ),
143 rEntryContext( rParentContext )
144 {
145 }
146
147 // SvXMLImportContext
148 virtual void SAL_CALL endFastElement( sal_Int32 nElement ) override;
149 virtual void SAL_CALL characters( const OUString &rChars ) override;
150};
151
152}
153
154//void ConvDicXMLImportContext::characters(const OUString & /*rChars*/)
155//{
156 /*
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).
161 */
162 //collapsing not done yet!
163
164//}
165
166css::uno::Reference<XFastContextHandler> ConvDicXMLImportContext::createFastChildContext(
167 sal_Int32 Element,
168 const css::uno::Reference< css::xml::sax::XFastAttributeList > & /*xAttrList*/ )
169{
171 return new ConvDicXMLDictionaryContext_Impl( GetConvDicImport() );
172 return nullptr;
173}
174
175
176void ConvDicXMLDictionaryContext_Impl::startFastElement( sal_Int32 /*nElement*/,
177 const css::uno::Reference< css::xml::sax::XFastAttributeList >& rxAttrList )
178{
179 for (auto &aIter : sax_fastparser::castToFastAttributeList( rxAttrList ))
180 {
181 switch (aIter.getToken())
182 {
184 nLanguage = LanguageTag::convertToLanguageType( aIter.toString() );
185 break;
187 nConversionType = GetConversionTypeFromText( aIter.toString() );
188 break;
189 default:
190 ;
191 }
192 }
193 GetConvDicImport().SetLanguage( nLanguage );
194 GetConvDicImport().SetConversionType( nConversionType );
195
196}
197
198css::uno::Reference<XFastContextHandler> ConvDicXMLDictionaryContext_Impl::createFastChildContext(
199 sal_Int32 Element,
200 const css::uno::Reference< css::xml::sax::XFastAttributeList > & /*xAttrList*/ )
201{
202 if ( Element == ConvDicXMLToken::ENTRY )
203 return new ConvDicXMLEntryTextContext_Impl( GetConvDicImport() );
204 return nullptr;
205}
206
207css::uno::Reference<XFastContextHandler> ConvDicXMLEntryTextContext_Impl::createFastChildContext(
208 sal_Int32 Element,
209 const css::uno::Reference< css::xml::sax::XFastAttributeList > & /*xAttrList*/ )
210{
211 if ( Element == ConvDicXMLToken::RIGHT_TEXT )
212 return new ConvDicXMLRightTextContext_Impl( GetConvDicImport(), *this );
213 return nullptr;
214}
215
216void ConvDicXMLEntryTextContext_Impl::startFastElement(
217 sal_Int32 /*Element*/,
218 const css::uno::Reference< css::xml::sax::XFastAttributeList >& rxAttrList )
219{
220 for (auto &aIter : sax_fastparser::castToFastAttributeList( rxAttrList ))
221 {
222 switch (aIter.getToken())
223 {
225 aLeftText = aIter.toString();
226 break;
227 default:
228 ;
229 }
230 }
231}
232
233
234void ConvDicXMLRightTextContext_Impl::characters( const OUString &rChars )
235{
236 aRightText += rChars;
237}
238
239void ConvDicXMLRightTextContext_Impl::endFastElement( sal_Int32 /*nElement*/ )
240{
241 ConvDic *pDic = GetConvDicImport().GetDic();
242 if (pDic)
243 pDic->AddEntry( rEntryContext.GetLeftText(), aRightText );
244}
245
246
248{
249 uno::Reference< document::XExporter > xExporter( this );
250 uno::Reference< document::XFilter > xFilter( xExporter, UNO_QUERY );
251 xFilter->filter( {} ); // calls exportDoc implicitly
252
253 return bSuccess;
254}
255
256
257ErrCode ConvDicXMLExport::exportDoc( enum ::xmloff::token::XMLTokenEnum /*eClass*/ )
258{
259 GetNamespaceMap_().Add( "tcd",
261
262 GetDocHandler()->startDocument();
263
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" );
268
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 );
273
276 {
277 SvXMLElementExport aRoot( *this, XML_NAMESPACE_TCD, "text-conversion-dictionary", true, true );
279 }
280
281 GetDocHandler()->endDocument();
282
283 bSuccess = true;
284 return ERRCODE_NONE;
285}
286
287
289{
290 // acquire sorted list of all keys
291 std::set<OUString> aKeySet;
292 for (auto const& elem : rDic.aFromLeft)
293 aKeySet.insert( elem.first );
294
295 for (const OUString& aLeftText : aKeySet)
296 {
297 AddAttribute( XML_NAMESPACE_TCD, "left-text", aLeftText );
298 if (rDic.pConvPropType) // property-type list available?
299 {
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 ) );
308 }
309 SvXMLElementExport aEntryMain( *this, XML_NAMESPACE_TCD,
310 "entry" , true, true );
311
312 std::pair< ConvMap::iterator, ConvMap::iterator > aRange =
313 rDic.aFromLeft.equal_range(aLeftText);
314 for (auto aIt = aRange.first; aIt != aRange.second; ++aIt)
315 {
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 );
321 }
322 }
323}
324
327 SvXMLImport ( comphelper::getProcessComponentContext(), "com.sun.star.lingu2.ConvDicXMLImport", SvXMLImportFlags::ALL ),
328 pDic ( pConvDic ), nLanguage(LANGUAGE_NONE), nConversionType(-1)
329{
331}
332
334 sal_Int32 Element,
335 const css::uno::Reference< css::xml::sax::XFastAttributeList > & /*xAttrList*/ )
336{
338 return new ConvDicXMLDictionaryContext_Impl( *this );
339 return nullptr;
340}
341
342/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
ErrCode exportDoc(enum ::xmloff::token::XMLTokenEnum eClass=::xmloff::token::XML_TOKEN_INVALID) override
Definition: convdicxml.cxx:257
void ExportContent_() override
Definition: convdicxml.cxx:288
ConvDic & rDic
Definition: convdicxml.hxx:41
ConvDicXMLImport(ConvDic *pConvDic)
! see comment for pDic member
Definition: convdicxml.cxx:326
virtual SvXMLImportContext * CreateFastContext(sal_Int32 Element, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList) override
Definition: convdicxml.cxx:333
sal_Int16 nConversionType
Definition: convdic.hxx:67
std::unique_ptr< PropTypeMap > pConvPropType
Definition: convdic.hxx:62
void AddEntry(const OUString &rLeftText, const OUString &rRightText)
Definition: convdic.cxx:272
ConvMap aFromLeft
Definition: convdic.hxx:59
LanguageType nLanguage
Definition: convdic.hxx:66
static OUString convertToBcp47(LanguageType nLangID)
static LanguageType convertToLanguageType(const css::lang::Locale &rLocale, bool bResolveSystem=true)
void AddAttribute(sal_uInt16 nPrefix, const OUString &rName, const OUString &rValue)
void Characters(const OUString &rChars)
SvXMLNamespaceMap & GetNamespaceMap_()
const css::uno::Reference< css::xml::sax::XDocumentHandler > & GetDocHandler() const
SvXMLImport & GetImport()
virtual css::uno::Reference< XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 Element, const css::uno::Reference< css::xml::sax::XFastAttributeList > &Attribs) override
sal_uInt16 Add(const OUString &rPrefix, const OUString &rName, sal_uInt16 nKey=XML_NAMESPACE_UNKNOWN)
constexpr OUStringLiteral CONV_TYPE_SCHINESE_TCHINESE
Definition: convdicxml.cxx:47
constexpr OUStringLiteral CONV_TYPE_HANGUL_HANJA
Definition: convdicxml.cxx:46
static sal_Int16 GetConversionTypeFromText(std::u16string_view rText)
Definition: convdicxml.cxx:60
static OUString ConversionTypeToText(sal_Int16 nConversionType)
Definition: convdicxml.cxx:50
constexpr OUStringLiteral XML_NAMESPACE_TCD_STRING
Definition: convdicxml.cxx:45
@ RIGHT_TEXT
Definition: convdicxml.hxx:68
@ TEXT_CONVERSION_DICTIONARY
Definition: convdicxml.hxx:67
@ ENTRY
Definition: convdicxml.hxx:69
#define DBG_ASSERT(sCon, aError)
float u
#define ERRCODE_NONE
#define LANGUAGE_NONE
Reference< XComponentContext > getProcessComponentContext()
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
XML_N_TCD
XML_LEFT_TEXT
XML_NP_TCD
XML_CONVERSION_TYPE
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
SvXMLImportFlags
constexpr sal_uInt16 XML_NAMESPACE_TCD
constexpr OStringLiteral XML_LANG