Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / linguistic / source / convdicxml.cxx
blobf4165abcadf8ba22d51ce528054c9ac45c57aa3c
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/nmspmap.hxx>
30 #include <xmloff/xmlnmspe.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 "Hangul / Hanja"
48 #define CONV_TYPE_SCHINESE_TCHINESE "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( const OUString &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;
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 void Characters( const OUString &rChars ) override;
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 )
103 nLanguage = LANGUAGE_NONE;
104 nConversionType = -1;
107 // SvXMLImportContext
108 virtual void SAL_CALL startFastElement( sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& Attribs ) override;
109 virtual css::uno::Reference<XFastContextHandler> SAL_CALL createFastChildContext(
110 sal_Int32 Element, const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList ) override;
114 class ConvDicXMLEntryTextContext_Impl :
115 public ConvDicXMLImportContext
117 OUString aLeftText;
119 public:
120 ConvDicXMLEntryTextContext_Impl( ConvDicXMLImport &rImport ) :
121 ConvDicXMLImportContext( rImport )
125 // SvXMLImportContext
126 virtual void SAL_CALL startFastElement( sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& Attribs ) override;
127 virtual css::uno::Reference<XFastContextHandler> SAL_CALL createFastChildContext(
128 sal_Int32 Element, const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList ) override;
130 const OUString & GetLeftText() const { return aLeftText; }
134 class ConvDicXMLRightTextContext_Impl :
135 public ConvDicXMLImportContext
137 OUString aRightText;
138 ConvDicXMLEntryTextContext_Impl &rEntryContext;
140 public:
141 ConvDicXMLRightTextContext_Impl(
142 ConvDicXMLImport &rImport,
143 ConvDicXMLEntryTextContext_Impl &rParentContext ) :
144 ConvDicXMLImportContext( rImport ),
145 rEntryContext( rParentContext )
149 // SvXMLImportContext
150 virtual void SAL_CALL endFastElement( sal_Int32 nElement ) override;
151 virtual void Characters( const OUString &rChars ) override;
153 const OUString & GetRightText() const { return aRightText; }
154 const OUString & GetLeftText() const { return rEntryContext.GetLeftText(); }
158 void ConvDicXMLImportContext::Characters(const OUString & /*rChars*/)
161 Whitespace occurring within the content of token elements is "trimmed"
162 from the ends (i.e. all whitespace at the beginning and end of the
163 content is removed), and "collapsed" internally (i.e. each sequence of
164 1 or more whitespace characters is replaced with one blank character).
166 //collapsing not done yet!
170 css::uno::Reference<XFastContextHandler> ConvDicXMLImportContext::createFastChildContext(
171 sal_Int32 Element,
172 const css::uno::Reference< css::xml::sax::XFastAttributeList > & /*xAttrList*/ )
174 if ( Element == ConvDicXMLToken::TEXT_CONVERSION_DICTIONARY )
175 return new ConvDicXMLDictionaryContext_Impl( GetConvDicImport() );
176 else
177 return new SvXMLImportContext( GetImport() );
181 void ConvDicXMLDictionaryContext_Impl::startFastElement( sal_Int32 /*nElement*/,
182 const css::uno::Reference< css::xml::sax::XFastAttributeList >& rxAttrList )
184 if ( rxAttrList.is() )
186 sax_fastparser::FastAttributeList *pAttribList =
187 sax_fastparser::FastAttributeList::castToFastAttributeList( rxAttrList );
189 for (auto &aIter : *pAttribList)
191 switch (aIter.getToken())
193 case XML_NAMESPACE_TCD | XML_LANG:
194 nLanguage = LanguageTag::convertToLanguageType( aIter.toString() );
195 break;
196 case XML_NAMESPACE_TCD | XML_CONVERSION_TYPE:
197 nConversionType = GetConversionTypeFromText( aIter.toString() );
198 break;
199 default:
204 GetConvDicImport().SetLanguage( nLanguage );
205 GetConvDicImport().SetConversionType( nConversionType );
209 css::uno::Reference<XFastContextHandler> ConvDicXMLDictionaryContext_Impl::createFastChildContext(
210 sal_Int32 Element,
211 const css::uno::Reference< css::xml::sax::XFastAttributeList > & /*xAttrList*/ )
213 if ( Element == ConvDicXMLToken::ENTRY )
214 return new ConvDicXMLEntryTextContext_Impl( GetConvDicImport() );
215 else
216 return new SvXMLImportContext(GetImport());
219 css::uno::Reference<XFastContextHandler> ConvDicXMLEntryTextContext_Impl::createFastChildContext(
220 sal_Int32 Element,
221 const css::uno::Reference< css::xml::sax::XFastAttributeList > & /*xAttrList*/ )
223 if ( Element == ConvDicXMLToken::RIGHT_TEXT )
224 return new ConvDicXMLRightTextContext_Impl( GetConvDicImport(), *this );
225 else
226 return new SvXMLImportContext(GetImport());
229 void ConvDicXMLEntryTextContext_Impl::startFastElement(
230 sal_Int32 /*Element*/,
231 const css::uno::Reference< css::xml::sax::XFastAttributeList >& rxAttrList )
233 if ( rxAttrList.is() )
235 sax_fastparser::FastAttributeList *pAttribList =
236 sax_fastparser::FastAttributeList::castToFastAttributeList( rxAttrList );
238 for (auto &aIter : *pAttribList)
240 switch (aIter.getToken())
242 case XML_NAMESPACE_TCD | XML_LEFT_TEXT:
243 aLeftText = aIter.toString();
244 break;
245 default:
253 void ConvDicXMLRightTextContext_Impl::Characters( const OUString &rChars )
255 aRightText += rChars;
258 void ConvDicXMLRightTextContext_Impl::endFastElement( sal_Int32 /*nElement*/ )
260 ConvDic *pDic = GetConvDicImport().GetDic();
261 if (pDic)
262 pDic->AddEntry( GetLeftText(), GetRightText() );
266 bool ConvDicXMLExport::Export()
268 uno::Reference< document::XExporter > xExporter( this );
269 uno::Reference< document::XFilter > xFilter( xExporter, UNO_QUERY );
270 uno::Sequence< beans::PropertyValue > aProps(0);
271 xFilter->filter( aProps ); // calls exportDoc implicitly
273 return bSuccess;
277 ErrCode ConvDicXMLExport::exportDoc( enum ::xmloff::token::XMLTokenEnum /*eClass*/ )
279 GetNamespaceMap_().Add( "tcd",
280 XML_NAMESPACE_TCD_STRING, XML_NAMESPACE_TCD );
282 GetDocHandler()->startDocument();
284 // Add xmlns line and some other arguments
285 AddAttribute( GetNamespaceMap_().GetAttrNameByKey( XML_NAMESPACE_TCD ),
286 GetNamespaceMap_().GetNameByKey( XML_NAMESPACE_TCD ) );
287 AddAttributeASCII( XML_NAMESPACE_TCD, "package", "org.openoffice.Office" );
289 OUString aIsoLang( LanguageTag::convertToBcp47( rDic.nLanguage ) );
290 AddAttribute( XML_NAMESPACE_TCD, "lang", aIsoLang );
291 OUString aConvType( ConversionTypeToText( rDic.nConversionType ) );
292 AddAttribute( XML_NAMESPACE_TCD, "conversion-type", aConvType );
294 //!! block necessary in order to have SvXMLElementExport d-tor called
295 //!! before the call to endDocument
297 SvXMLElementExport aRoot( *this, XML_NAMESPACE_TCD, "text-conversion-dictionary", true, true );
298 ExportContent_();
301 GetDocHandler()->endDocument();
303 bSuccess = true;
304 return ERRCODE_NONE;
308 void ConvDicXMLExport::ExportContent_()
310 // acquire sorted list of all keys
311 ConvMapKeySet aKeySet;
312 for (auto const& elem : rDic.aFromLeft)
313 aKeySet.insert( elem.first );
315 for (const OUString& aLeftText : aKeySet)
317 AddAttribute( XML_NAMESPACE_TCD, "left-text", aLeftText );
318 if (rDic.pConvPropType) // property-type list available?
320 sal_Int16 nPropertyType = -1;
321 PropTypeMap::iterator aIt2 = rDic.pConvPropType->find( aLeftText );
322 if (aIt2 != rDic.pConvPropType->end())
323 nPropertyType = (*aIt2).second;
324 DBG_ASSERT( nPropertyType, "property-type not found" );
325 if (nPropertyType == -1)
326 nPropertyType = ConversionPropertyType::NOT_DEFINED;
327 AddAttribute( XML_NAMESPACE_TCD, "property-type", OUString::number( nPropertyType ) );
329 SvXMLElementExport aEntryMain( *this, XML_NAMESPACE_TCD,
330 "entry" , true, true );
332 pair< ConvMap::iterator, ConvMap::iterator > aRange =
333 rDic.aFromLeft.equal_range(aLeftText);
334 for (auto aIt = aRange.first; aIt != aRange.second; ++aIt)
336 DBG_ASSERT( aLeftText == (*aIt).first, "key <-> entry mismatch" );
337 OUString aRightText( (*aIt).second );
338 SvXMLElementExport aEntryRightText( *this, XML_NAMESPACE_TCD,
339 "right-text" , true, false );
340 Characters( aRightText );
345 //!! see comment for pDic member
346 ConvDicXMLImport::ConvDicXMLImport( ConvDic *pConvDic ) :
347 SvXMLImport ( comphelper::getProcessComponentContext(), "com.sun.star.lingu2.ConvDicXMLImport", SvXMLImportFlags::ALL ),
348 pDic ( pConvDic )
350 nLanguage = LANGUAGE_NONE;
351 nConversionType = -1;
352 GetNamespaceMap().Add( GetXMLToken(XML_NP_TCD), GetXMLToken(XML_N_TCD), XML_NAMESPACE_TCD);
355 SvXMLImportContext * ConvDicXMLImport::CreateFastContext(
356 sal_Int32 Element,
357 const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList )
359 if( Element == ConvDicXMLToken::TEXT_CONVERSION_DICTIONARY )
360 return new ConvDicXMLDictionaryContext_Impl( *this );
361 else
362 return SvXMLImport::CreateFastContext( Element, xAttrList );
365 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */