LanguageTool: don't crash if REST protocol isn't set
[LibreOffice.git] / sfx2 / source / doc / docfac.cxx
blobcc041670f99793e24b3215f6ae84b3eaed1af72f
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 <com/sun/star/container/XNameAccess.hpp>
21 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
22 #include <com/sun/star/document/XTypeDetection.hpp>
23 #include <com/sun/star/frame/ModuleManager.hpp>
24 #include <com/sun/star/frame/XLoadable.hpp>
25 #include <com/sun/star/frame/XStorable.hpp>
26 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
27 #include <comphelper/processfactory.hxx>
28 #include <comphelper/propertyvalue.hxx>
29 #include <unotools/moduleoptions.hxx>
30 #include <comphelper/sequenceashashmap.hxx>
31 #include <comphelper/configurationhelper.hxx>
33 #include <sfx2/docfilt.hxx>
34 #include <sfx2/docfac.hxx>
35 #include <sfx2/viewfac.hxx>
36 #include <sfx2/fcontnr.hxx>
37 #include <sfx2/module.hxx>
38 #include "syspath.hxx"
39 #include <osl/file.hxx>
40 #include <osl/security.hxx>
42 #include <sal/log.hxx>
43 #include <tools/debug.hxx>
44 #include <tools/globname.hxx>
46 #include <memory>
48 using namespace ::com::sun::star;
51 struct SfxObjectFactory_Impl
53 std::vector<SfxViewFactory*> aViewFactoryArr;// List of <SfxViewFactory>s
54 OUString aServiceName;
55 SfxFilterContainer* pFilterContainer;
56 SfxModule* pModule;
57 SvGlobalName aClassName;
59 SfxObjectFactory_Impl() :
60 pFilterContainer ( nullptr ),
61 pModule ( nullptr )
65 SfxFilterContainer* SfxObjectFactory::GetFilterContainer() const
67 return pImpl->pFilterContainer;
70 SfxObjectFactory::SfxObjectFactory
72 const SvGlobalName& rName,
73 const OUString& sName
74 ) : m_sFactoryName( sName ),
75 pImpl( new SfxObjectFactory_Impl )
77 pImpl->pFilterContainer = new SfxFilterContainer( m_sFactoryName );
78 pImpl->aClassName = rName;
81 SfxObjectFactory::~SfxObjectFactory()
83 delete pImpl->pFilterContainer;
87 void SfxObjectFactory::RegisterViewFactory
89 SfxViewFactory &rFactory
92 #if OSL_DEBUG_LEVEL > 0
94 const OUString sViewName( rFactory.GetAPIViewName() );
95 for (auto const& viewFactory : pImpl->aViewFactoryArr)
97 if ( viewFactory->GetAPIViewName() != sViewName )
98 continue;
99 SAL_WARN( "sfx", "SfxObjectFactory::RegisterViewFactory: duplicate view name: " << sViewName );
100 break;
103 #endif
104 auto it = std::find_if(pImpl->aViewFactoryArr.begin(), pImpl->aViewFactoryArr.end(),
105 [&rFactory](SfxViewFactory* pFactory) { return pFactory->GetOrdinal() > rFactory.GetOrdinal(); });
106 pImpl->aViewFactoryArr.insert(it, &rFactory);
110 sal_uInt16 SfxObjectFactory::GetViewFactoryCount() const
112 return pImpl->aViewFactoryArr.size();
116 SfxViewFactory& SfxObjectFactory::GetViewFactory(sal_uInt16 i) const
118 return *pImpl->aViewFactoryArr[i];
122 SfxModule* SfxObjectFactory::GetModule() const
124 return pImpl->pModule;
127 void SfxObjectFactory::SetModule_Impl( SfxModule *pMod )
129 pImpl->pModule = pMod;
132 void SfxObjectFactory::SetSystemTemplate( const OUString& rServiceName, const OUString& rTemplateName )
134 static const int nMaxPathSize = 16000;
136 const OUString sConfPath = "Office/Factories/" + rServiceName;
137 static constexpr OUStringLiteral PROP_DEF_TEMPL_CHANGED
138 = u"ooSetupFactorySystemDefaultTemplateChanged";
140 static const char DEF_TPL_STR[] = "/soffice.";
142 OUString sUserTemplateURL;
143 OUString sPath;
144 sal_Unicode aPathBuffer[nMaxPathSize];
145 if ( SystemPath::GetUserTemplateLocation( aPathBuffer, nMaxPathSize ))
146 sPath = OUString( aPathBuffer );
147 osl::FileBase::getFileURLFromSystemPath( sPath, sUserTemplateURL );
149 if ( sUserTemplateURL.isEmpty())
150 return;
154 uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
155 uno::Reference< uno::XInterface > xConfig = ::comphelper::ConfigurationHelper::openConfig(
156 ::comphelper::getProcessComponentContext(), "/org.openoffice.Setup", ::comphelper::EConfigurationModes::Standard );
158 OUString aActualFilter;
159 ::comphelper::ConfigurationHelper::readRelativeKey( xConfig, sConfPath, "ooSetupFactoryActualFilter" ) >>= aActualFilter;
160 bool bChanged(false);
161 ::comphelper::ConfigurationHelper::readRelativeKey( xConfig, sConfPath, PROP_DEF_TEMPL_CHANGED ) >>= bChanged;
163 uno::Reference< container::XNameAccess > xFilterFactory(
164 xFactory->createInstance( "com.sun.star.document.FilterFactory" ), uno::UNO_QUERY_THROW );
165 uno::Reference< container::XNameAccess > xTypeDetection(
166 xFactory->createInstance( "com.sun.star.document.TypeDetection" ), uno::UNO_QUERY_THROW );
168 OUString aActualFilterTypeName;
169 uno::Sequence< beans::PropertyValue > aActuralFilterData;
170 xFilterFactory->getByName( aActualFilter ) >>= aActuralFilterData;
171 for ( const auto& rProp : std::as_const(aActuralFilterData) )
172 if ( rProp.Name == "Type" )
173 rProp.Value >>= aActualFilterTypeName;
174 ::comphelper::SequenceAsHashMap aProps1( xTypeDetection->getByName( aActualFilterTypeName ) );
175 uno::Sequence< OUString > aAllExt =
176 aProps1.getUnpackedValueOrDefault("Extensions", uno::Sequence< OUString >() );
177 //To-do: check if aAllExt is empty first
178 const OUString aExt = DEF_TPL_STR + aAllExt[0];
180 sUserTemplateURL += aExt;
182 uno::Reference<ucb::XSimpleFileAccess3> xSimpleFileAccess(
183 ucb::SimpleFileAccess::create( ::comphelper::getComponentContext(xFactory) ) );
185 OUString aBackupURL;
186 ::osl::Security().getConfigDir(aBackupURL);
187 aBackupURL += "/temp";
189 if ( !xSimpleFileAccess->exists( aBackupURL ) )
190 xSimpleFileAccess->createFolder( aBackupURL );
192 aBackupURL += aExt;
194 if ( !rTemplateName.isEmpty() )
196 if ( xSimpleFileAccess->exists( sUserTemplateURL ) && !bChanged )
197 xSimpleFileAccess->copy( sUserTemplateURL, aBackupURL );
199 uno::Reference< document::XTypeDetection > xTypeDetector( xTypeDetection, uno::UNO_QUERY );
200 ::comphelper::SequenceAsHashMap aProps2( xTypeDetection->getByName( xTypeDetector->queryTypeByURL( rTemplateName ) ) );
201 OUString aFilterName =
202 aProps2.getUnpackedValueOrDefault("PreferredFilter", OUString() );
204 uno::Sequence< beans::PropertyValue > aArgs{
205 comphelper::makePropertyValue("FilterName", aFilterName),
206 comphelper::makePropertyValue("AsTemplate", true),
207 comphelper::makePropertyValue("URL", rTemplateName)
210 uno::Reference< frame::XLoadable > xLoadable( xFactory->createInstance( rServiceName ), uno::UNO_QUERY );
211 xLoadable->load( aArgs );
213 aArgs.realloc( 2 );
214 auto pArgs = aArgs.getArray();
215 pArgs[1].Name = "Overwrite";
216 pArgs[1].Value <<= true;
218 uno::Reference< frame::XStorable > xStorable( xLoadable, uno::UNO_QUERY );
219 xStorable->storeToURL( sUserTemplateURL, aArgs );
220 ::comphelper::ConfigurationHelper::writeRelativeKey( xConfig, sConfPath, PROP_DEF_TEMPL_CHANGED, uno::makeAny( true ));
221 ::comphelper::ConfigurationHelper::flush( xConfig );
223 else
225 DBG_ASSERT( bChanged, "invalid ooSetupFactorySystemDefaultTemplateChanged value!" );
227 xSimpleFileAccess->copy( aBackupURL, sUserTemplateURL );
228 xSimpleFileAccess->kill( aBackupURL );
229 ::comphelper::ConfigurationHelper::writeRelativeKey( xConfig, sConfPath, PROP_DEF_TEMPL_CHANGED, uno::makeAny( false ));
230 ::comphelper::ConfigurationHelper::flush( xConfig );
233 catch(const uno::Exception&)
238 void SfxObjectFactory::SetStandardTemplate( const OUString& rServiceName, const OUString& rTemplate )
240 SvtModuleOptions::EFactory eFac = SvtModuleOptions::ClassifyFactoryByServiceName(rServiceName);
241 if (eFac == SvtModuleOptions::EFactory::UNKNOWN_FACTORY)
242 eFac = SvtModuleOptions::ClassifyFactoryByShortName(rServiceName);
243 if (eFac != SvtModuleOptions::EFactory::UNKNOWN_FACTORY)
245 SetSystemTemplate( rServiceName, rTemplate );
246 SvtModuleOptions().SetFactoryStandardTemplate(eFac, rTemplate);
250 OUString SfxObjectFactory::GetStandardTemplate( const OUString& rServiceName )
252 SvtModuleOptions::EFactory eFac = SvtModuleOptions::ClassifyFactoryByServiceName(rServiceName);
253 if (eFac == SvtModuleOptions::EFactory::UNKNOWN_FACTORY)
254 eFac = SvtModuleOptions::ClassifyFactoryByShortName(rServiceName);
256 if (eFac != SvtModuleOptions::EFactory::UNKNOWN_FACTORY)
257 return SvtModuleOptions().GetFactoryStandardTemplate(eFac);
259 return OUString();
262 std::shared_ptr<const SfxFilter> SfxObjectFactory::GetTemplateFilter() const
264 sal_uInt16 nVersion=0;
265 SfxFilterMatcher aMatcher ( m_sFactoryName );
266 SfxFilterMatcherIter aIter( aMatcher );
267 std::shared_ptr<const SfxFilter> pFilter;
268 std::shared_ptr<const SfxFilter> pTemp = aIter.First();
269 while ( pTemp )
271 if( pTemp->IsOwnFormat() && pTemp->IsOwnTemplateFormat() && ( pTemp->GetVersion() > nVersion ) )
273 pFilter = pTemp;
274 nVersion = static_cast<sal_uInt16>(pTemp->GetVersion());
277 pTemp = aIter.Next();
280 return pFilter;
283 void SfxObjectFactory::SetDocumentServiceName( const OUString& rServiceName )
285 pImpl->aServiceName = rServiceName;
288 const OUString& SfxObjectFactory::GetDocumentServiceName() const
290 return pImpl->aServiceName;
293 const SvGlobalName& SfxObjectFactory::GetClassId() const
295 return pImpl->aClassName;
298 OUString SfxObjectFactory::GetFactoryURL() const
300 return "private:factory/" + m_sFactoryName;
303 OUString SfxObjectFactory::GetModuleName() const
307 css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
309 css::uno::Reference< css::frame::XModuleManager2 > xModuleManager(
310 css::frame::ModuleManager::create(xContext));
312 ::comphelper::SequenceAsHashMap aPropSet( xModuleManager->getByName(GetDocumentServiceName()) );
313 return aPropSet.getUnpackedValueOrDefault("ooSetupFactoryUIName", OUString());
315 catch(const css::uno::RuntimeException&)
317 throw;
319 catch(const css::uno::Exception&)
323 return OUString();
327 sal_uInt16 SfxObjectFactory::GetViewNo_Impl( const SfxInterfaceId i_nViewId, const sal_uInt16 i_nFallback ) const
329 for ( sal_uInt16 curViewNo = 0; curViewNo < GetViewFactoryCount(); ++curViewNo )
331 const SfxInterfaceId curViewId = GetViewFactory( curViewNo ).GetOrdinal();
332 if ( i_nViewId == curViewId )
333 return curViewNo;
335 return i_nFallback;
338 SfxViewFactory* SfxObjectFactory::GetViewFactoryByViewName( std::u16string_view i_rViewName ) const
340 for ( sal_uInt16 nViewNo = 0;
341 nViewNo < GetViewFactoryCount();
342 ++nViewNo
345 SfxViewFactory& rViewFac( GetViewFactory( nViewNo ) );
346 if ( ( rViewFac.GetAPIViewName() == i_rViewName )
347 || ( rViewFac.GetLegacyViewName() == i_rViewName )
349 return &rViewFac;
351 return nullptr;
354 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */