LCOV - code coverage report
Current view: top level - linguistic/source - thesdsp.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 24 104 23.1 %
Date: 2014-11-03 Functions: 5 11 45.5 %
Legend: Lines: hit not hit

          Line data    Source code
       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 <i18nlangtag/lang.h>
      21             : #include <tools/debug.hxx>
      22             : #include <svl/lngmisc.hxx>
      23             : 
      24             : #include <cppuhelper/factory.hxx>
      25             : #include <com/sun/star/registry/XRegistryKey.hpp>
      26             : #include <com/sun/star/beans/XPropertySet.hpp>
      27             : #include <comphelper/processfactory.hxx>
      28             : #include <osl/mutex.hxx>
      29             : 
      30             : #include "thesdsp.hxx"
      31             : #include "linguistic/lngprops.hxx"
      32             : 
      33             : using namespace osl;
      34             : using namespace com::sun::star;
      35             : using namespace com::sun::star::beans;
      36             : using namespace com::sun::star::lang;
      37             : using namespace com::sun::star::uno;
      38             : using namespace com::sun::star::linguistic2;
      39             : using namespace linguistic;
      40             : 
      41             : 
      42             : 
      43           0 : static bool SvcListHasLanguage(
      44             :         const Sequence< Reference< XThesaurus > > &rRefs,
      45             :         const Locale &rLocale )
      46             : {
      47           0 :     bool bHasLanguage = false;
      48             : 
      49           0 :     const Reference< XThesaurus > *pRef = rRefs.getConstArray();
      50           0 :     sal_Int32 nLen = rRefs.getLength();
      51           0 :     for (sal_Int32 k = 0;  k < nLen  &&  !bHasLanguage;  ++k)
      52             :     {
      53           0 :         if (pRef[k].is())
      54           0 :             bHasLanguage = pRef[k]->hasLocale( rLocale );
      55             :     }
      56             : 
      57           0 :     return bHasLanguage;
      58             : }
      59             : 
      60             : 
      61             : 
      62          44 : ThesaurusDispatcher::ThesaurusDispatcher()
      63             : {
      64          44 : }
      65             : 
      66             : 
      67         126 : ThesaurusDispatcher::~ThesaurusDispatcher()
      68             : {
      69          42 :     ClearSvcList();
      70          84 : }
      71             : 
      72             : 
      73          42 : void ThesaurusDispatcher::ClearSvcList()
      74             : {
      75             :     // release memory for each table entry
      76          42 :     ThesSvcByLangMap_t aTmp;
      77          42 :     aSvcMap.swap( aTmp );
      78          42 : }
      79             : 
      80             : 
      81             : Sequence< Locale > SAL_CALL
      82           0 :     ThesaurusDispatcher::getLocales()
      83             :         throw(RuntimeException, std::exception)
      84             : {
      85           0 :     MutexGuard  aGuard( GetLinguMutex() );
      86             : 
      87           0 :     Sequence< Locale > aLocales( static_cast< sal_Int32 >(aSvcMap.size()) );
      88           0 :     Locale *pLocales = aLocales.getArray();
      89           0 :     ThesSvcByLangMap_t::const_iterator aIt;
      90           0 :     for (aIt = aSvcMap.begin();  aIt != aSvcMap.end();  ++aIt)
      91             :     {
      92           0 :         *pLocales++ = LanguageTag::convertToLocale( aIt->first );
      93             :     }
      94           0 :     return aLocales;
      95             : }
      96             : 
      97             : 
      98             : sal_Bool SAL_CALL
      99           0 :     ThesaurusDispatcher::hasLocale( const Locale& rLocale )
     100             :         throw(RuntimeException, std::exception)
     101             : {
     102           0 :     MutexGuard  aGuard( GetLinguMutex() );
     103           0 :     ThesSvcByLangMap_t::const_iterator aIt( aSvcMap.find( LinguLocaleToLanguage( rLocale ) ) );
     104           0 :     return aIt != aSvcMap.end();
     105             : }
     106             : 
     107             : 
     108             : Sequence< Reference< XMeaning > > SAL_CALL
     109           0 :     ThesaurusDispatcher::queryMeanings(
     110             :             const OUString& rTerm, const Locale& rLocale,
     111             :             const PropertyValues& rProperties )
     112             :         throw(IllegalArgumentException, RuntimeException, std::exception)
     113             : {
     114           0 :     MutexGuard  aGuard( GetLinguMutex() );
     115             : 
     116           0 :     Sequence< Reference< XMeaning > >   aMeanings;
     117             : 
     118           0 :     sal_Int16 nLanguage = LinguLocaleToLanguage( rLocale );
     119           0 :     if (LinguIsUnspecified( nLanguage) || rTerm.isEmpty())
     120           0 :         return aMeanings;
     121             : 
     122             :     // search for entry with that language
     123           0 :     ThesSvcByLangMap_t::iterator    aIt( aSvcMap.find( nLanguage ) );
     124           0 :     LangSvcEntries_Thes     *pEntry = aIt != aSvcMap.end() ? aIt->second.get() : NULL;
     125             : 
     126           0 :     if (pEntry)
     127             :     {
     128           0 :         OUString aChkWord( rTerm );
     129           0 :         aChkWord = aChkWord.replace( SVT_HARD_SPACE, ' ' );
     130           0 :         RemoveHyphens( aChkWord );
     131           0 :         if (IsIgnoreControlChars( rProperties, GetPropSet() ))
     132           0 :             RemoveControlChars( aChkWord );
     133             : 
     134           0 :         sal_Int32 nLen = pEntry->aSvcRefs.getLength();
     135             :         DBG_ASSERT( nLen == pEntry->aSvcImplNames.getLength(),
     136             :                 "lng : sequence length mismatch");
     137             :         DBG_ASSERT( pEntry->nLastTriedSvcIndex < nLen,
     138             :                 "lng : index out of range");
     139             : 
     140           0 :         sal_Int32 i = 0;
     141             : 
     142             :         // try already instantiated services first
     143             :         {
     144           0 :             const Reference< XThesaurus > *pRef = pEntry->aSvcRefs.getConstArray();
     145           0 :             while (i <= pEntry->nLastTriedSvcIndex
     146           0 :                    &&  aMeanings.getLength() == 0)
     147             :             {
     148           0 :                 if (pRef[i].is()  &&  pRef[i]->hasLocale( rLocale ))
     149           0 :                     aMeanings = pRef[i]->queryMeanings( aChkWord, rLocale, rProperties );
     150           0 :                 ++i;
     151             :             }
     152             :         }
     153             : 
     154             :         // if still no result instantiate new services and try those
     155           0 :         if (aMeanings.getLength() == 0
     156           0 :             &&  pEntry->nLastTriedSvcIndex < nLen - 1)
     157             :         {
     158           0 :             const OUString *pImplNames = pEntry->aSvcImplNames.getConstArray();
     159           0 :             Reference< XThesaurus > *pRef = pEntry->aSvcRefs.getArray();
     160             : 
     161             :             Reference< XComponentContext > xContext(
     162           0 :                 comphelper::getProcessComponentContext() );
     163             : 
     164             :             // build service initialization argument
     165           0 :             Sequence< Any > aArgs(1);
     166           0 :             aArgs.getArray()[0] <<= GetPropSet();
     167             : 
     168           0 :             while (i < nLen  &&  aMeanings.getLength() == 0)
     169             :             {
     170             :                 // create specific service via it's implementation name
     171           0 :                 Reference< XThesaurus > xThes;
     172             :                 try
     173             :                 {
     174           0 :                     xThes = Reference< XThesaurus >(
     175           0 :                                 xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
     176           0 :                                     pImplNames[i], aArgs, xContext ),
     177           0 :                                 UNO_QUERY );
     178             :                 }
     179           0 :                 catch (uno::Exception &)
     180             :                 {
     181             :                     DBG_ASSERT( false, "createInstanceWithArguments failed" );
     182             :                 }
     183           0 :                 pRef[i] = xThes;
     184             : 
     185           0 :                 if (xThes.is()  &&  xThes->hasLocale( rLocale ))
     186           0 :                     aMeanings = xThes->queryMeanings( aChkWord, rLocale, rProperties );
     187             : 
     188           0 :                 pEntry->nLastTriedSvcIndex = (sal_Int16) i;
     189           0 :                 ++i;
     190           0 :             }
     191             : 
     192             :             // if language is not supported by any of the services
     193             :             // remove it from the list.
     194           0 :             if (i == nLen  &&  aMeanings.getLength() == 0)
     195             :             {
     196           0 :                 if (!SvcListHasLanguage( pEntry->aSvcRefs, rLocale ))
     197           0 :                     aSvcMap.erase( nLanguage );
     198           0 :             }
     199           0 :         }
     200             :     }
     201             : 
     202           0 :     return aMeanings;
     203             : }
     204             : 
     205             : 
     206        1012 : void ThesaurusDispatcher::SetServiceList( const Locale &rLocale,
     207             :         const Sequence< OUString > &rSvcImplNames )
     208             : {
     209        1012 :     MutexGuard  aGuard( GetLinguMutex() );
     210             : 
     211        1012 :     sal_Int16 nLanguage = LinguLocaleToLanguage( rLocale );
     212             : 
     213        1012 :     sal_Int32 nLen = rSvcImplNames.getLength();
     214        1012 :     if (0 == nLen)
     215             :         // remove entry
     216           0 :         aSvcMap.erase( nLanguage );
     217             :     else
     218             :     {
     219             :         // modify/add entry
     220        1012 :         LangSvcEntries_Thes *pEntry = aSvcMap[ nLanguage ].get();
     221        1012 :         if (pEntry)
     222             :         {
     223         220 :             pEntry->Clear();
     224         220 :             pEntry->aSvcImplNames = rSvcImplNames;
     225         220 :             pEntry->aSvcRefs = Sequence< Reference < XThesaurus > >( nLen );
     226             :         }
     227             :         else
     228             :         {
     229         792 :             boost::shared_ptr< LangSvcEntries_Thes > pTmpEntry( new LangSvcEntries_Thes( rSvcImplNames ) );
     230         792 :             pTmpEntry->aSvcRefs = Sequence< Reference < XThesaurus > >( nLen );
     231         792 :             aSvcMap[ nLanguage ] = pTmpEntry;
     232             :         }
     233        1012 :     }
     234        1012 : }
     235             : 
     236             : 
     237             : Sequence< OUString >
     238           0 :     ThesaurusDispatcher::GetServiceList( const Locale &rLocale ) const
     239             : {
     240           0 :     MutexGuard  aGuard( GetLinguMutex() );
     241             : 
     242           0 :     Sequence< OUString > aRes;
     243             : 
     244             :     // search for entry with that language and use data from that
     245           0 :     sal_Int16 nLanguage = LinguLocaleToLanguage( rLocale );
     246           0 :     const ThesSvcByLangMap_t::const_iterator  aIt( aSvcMap.find( nLanguage ) );
     247           0 :     const LangSvcEntries_Thes       *pEntry = aIt != aSvcMap.end() ? aIt->second.get() : NULL;
     248           0 :     if (pEntry)
     249           0 :         aRes = pEntry->aSvcImplNames;
     250             : 
     251           0 :     return aRes;
     252             : }
     253             : 
     254             : 
     255           0 : LinguDispatcher::DspType ThesaurusDispatcher::GetDspType() const
     256             : {
     257           0 :     return DSP_THES;
     258             : }
     259             : 
     260             : 
     261             : 
     262             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10