fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / ucb / source / ucp / cmis / cmis_repo_content.cxx
blob86be92cd8865e6ac0af8fc24158346cf9f34e9cc
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/.
8 */
10 #include <com/sun/star/beans/PropertyAttribute.hpp>
11 #include <com/sun/star/beans/PropertyValue.hpp>
12 #include <com/sun/star/beans/XPropertySetInfo.hpp>
13 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
14 #include <com/sun/star/task/XInteractionHandler.hpp>
15 #include <com/sun/star/ucb/XCommandInfo.hpp>
16 #include <com/sun/star/ucb/XDynamicResultSet.hpp>
17 #include <com/sun/star/ucb/XProgressHandler.hpp>
18 #ifndef SYSTEM_CURL
19 #include <com/sun/star/xml/crypto/XDigestContext.hpp>
20 #include <com/sun/star/xml/crypto/XDigestContextSupplier.hpp>
21 #include <com/sun/star/xml/crypto/DigestID.hpp>
22 #include <com/sun/star/xml/crypto/NSSInitializer.hpp>
23 #endif
25 #include <comphelper/processfactory.hxx>
26 #include <config_oauth2.h>
27 #include <rtl/uri.hxx>
28 #include <ucbhelper/cancelcommandexecution.hxx>
29 #include <ucbhelper/commandenvironment.hxx>
30 #include <ucbhelper/contentidentifier.hxx>
31 #include <ucbhelper/propertyvalueset.hxx>
32 #include <ucbhelper/proxydecider.hxx>
34 #include "auth_provider.hxx"
35 #include "certvalidation_handler.hxx"
36 #include "cmis_content.hxx"
37 #include "cmis_provider.hxx"
38 #include "cmis_repo_content.hxx"
39 #include "cmis_resultset.hxx"
40 #include <boost/scoped_ptr.hpp>
42 #define OUSTR_TO_STDSTR(s) string( OUStringToOString( s, RTL_TEXTENCODING_UTF8 ).getStr() )
43 #define STD_TO_OUSTR( str ) OUString( str.c_str(), str.length( ), RTL_TEXTENCODING_UTF8 )
45 using namespace com::sun::star;
46 using namespace std;
48 namespace cmis
50 RepoContent::RepoContent( const uno::Reference< uno::XComponentContext >& rxContext,
51 ContentProvider *pProvider, const uno::Reference< ucb::XContentIdentifier >& Identifier,
52 vector< libcmis::RepositoryPtr > aRepos )
53 throw ( ucb::ContentCreationException )
54 : ContentImplHelper( rxContext, pProvider, Identifier ),
55 m_pProvider( pProvider ),
56 m_aURL( Identifier->getContentIdentifier( ) ),
57 m_sRepositoryId( ),
58 m_aRepositories( aRepos )
60 // Split the URL into bits
61 OUString sURL = m_xIdentifier->getContentIdentifier( );
62 SAL_INFO( "ucb.ucp.cmis", "RepoContent::RepoContent() " << sURL );
64 m_sRepositoryId = m_aURL.getObjectPath();
65 if (!m_sRepositoryId.isEmpty() && m_sRepositoryId[0] == '/')
66 m_sRepositoryId = m_sRepositoryId.copy(1);
69 RepoContent::~RepoContent()
73 uno::Any RepoContent::getBadArgExcept()
75 return uno::makeAny( lang::IllegalArgumentException(
76 OUString("Wrong argument type!"),
77 static_cast< cppu::OWeakObject * >( this ), -1) );
80 uno::Reference< sdbc::XRow > RepoContent::getPropertyValues(
81 const uno::Sequence< beans::Property >& rProperties,
82 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
84 rtl::Reference< ::ucbhelper::PropertyValueSet > xRow = new ::ucbhelper::PropertyValueSet( m_xContext );
86 sal_Int32 nProps;
87 const beans::Property* pProps;
89 nProps = rProperties.getLength();
90 pProps = rProperties.getConstArray();
92 for( sal_Int32 n = 0; n < nProps; ++n )
94 const beans::Property& rProp = pProps[ n ];
96 try
98 if ( rProp.Name == "IsDocument" )
100 xRow->appendBoolean( rProp, false );
102 else if ( rProp.Name == "IsFolder" )
104 xRow->appendBoolean( rProp, true );
106 else if ( rProp.Name == "Title" )
108 xRow->appendString( rProp, STD_TO_OUSTR( getRepository( xEnv )->getName( ) ) );
110 else if ( rProp.Name == "IsReadOnly" )
112 xRow->appendBoolean( rProp, true );
114 else
116 xRow->appendVoid( rProp );
117 SAL_INFO( "ucb.ucp.cmis", "Looking for unsupported property " << rProp.Name );
120 catch (const libcmis::Exception&)
122 xRow->appendVoid( rProp );
126 return uno::Reference< sdbc::XRow >( xRow.get() );
129 void RepoContent::getRepositories( const uno::Reference< ucb::XCommandEnvironment > & xEnv )
131 #ifndef SYSTEM_CURL
132 // Initialize NSS library to make sure libcmis (and curl) can access CACERTs using NSS
133 // when using internal libcurl.
134 uno::Reference< com::sun::star::xml::crypto::XNSSInitializer >
135 xNSSInitializer = com::sun::star::xml::crypto::NSSInitializer::create( m_xContext );
137 uno::Reference< com::sun::star::xml::crypto::XDigestContext > xDigestContext(
138 xNSSInitializer->getDigestContext( com::sun::star::xml::crypto::DigestID::SHA256,
139 uno::Sequence< beans::NamedValue >() ),
140 uno::UNO_SET_THROW );
141 #endif
143 // Set the proxy if needed. We are doing that all times as the proxy data shouldn't be cached.
144 ucbhelper::InternetProxyDecider aProxyDecider( m_xContext );
145 INetURLObject aBindingUrl( m_aURL.getBindingUrl( ) );
146 const ucbhelper::InternetProxyServer& rProxy = aProxyDecider.getProxy(
147 INetURLObject::GetScheme( aBindingUrl.GetProtocol( ) ), aBindingUrl.GetHost(), aBindingUrl.GetPort() );
148 OUString sProxy = rProxy.aName;
149 if ( rProxy.nPort > 0 )
150 sProxy += ":" + OUString::number( rProxy.nPort );
151 libcmis::SessionFactory::setProxySettings( OUSTR_TO_STDSTR( sProxy ), string(), string(), string() );
153 if ( m_aRepositories.empty() )
155 // Set the SSL Validation handler
156 libcmis::CertValidationHandlerPtr certHandler(
157 new CertValidationHandler( xEnv, m_xContext, aBindingUrl.GetHost( ) ) );
158 libcmis::SessionFactory::setCertificateValidationHandler( certHandler );
160 // Get the auth credentials
161 AuthProvider authProvider( xEnv, m_xIdentifier->getContentIdentifier( ), m_aURL.getBindingUrl( ) );
162 AuthProvider::setXEnv( xEnv );
164 string rUsername = OUSTR_TO_STDSTR( m_aURL.getUsername( ) );
165 string rPassword = OUSTR_TO_STDSTR( m_aURL.getPassword( ) );
166 if ( authProvider.authenticationQuery( rUsername, rPassword ) )
170 // Create a session to get repositories
171 libcmis::OAuth2DataPtr oauth2Data;
172 if ( m_aURL.getBindingUrl( ) == GDRIVE_BASE_URL )
173 oauth2Data.reset( new libcmis::OAuth2Data(
174 GDRIVE_AUTH_URL, GDRIVE_TOKEN_URL,
175 GDRIVE_SCOPE, GDRIVE_REDIRECT_URI,
176 GDRIVE_CLIENT_ID, GDRIVE_CLIENT_SECRET ) );
177 if ( m_aURL.getBindingUrl().startsWith( ALFRESCO_CLOUD_BASE_URL ) )
178 oauth2Data.reset( new libcmis::OAuth2Data(
179 ALFRESCO_CLOUD_AUTH_URL, ALFRESCO_CLOUD_TOKEN_URL,
180 ALFRESCO_CLOUD_SCOPE, ALFRESCO_CLOUD_REDIRECT_URI,
181 ALFRESCO_CLOUD_CLIENT_ID, ALFRESCO_CLOUD_CLIENT_SECRET ) );
182 if ( m_aURL.getBindingUrl( ) == ONEDRIVE_BASE_URL )
184 libcmis::SessionFactory::setOAuth2AuthCodeProvider( authProvider.onedriveAuthCodeFallback );
185 oauth2Data.reset( new libcmis::OAuth2Data(
186 ONEDRIVE_AUTH_URL, ONEDRIVE_TOKEN_URL,
187 ONEDRIVE_SCOPE, ONEDRIVE_REDIRECT_URI,
188 ONEDRIVE_CLIENT_ID, ONEDRIVE_CLIENT_SECRET ) );
191 boost::scoped_ptr<libcmis::Session> session(libcmis::SessionFactory::createSession(
192 OUSTR_TO_STDSTR( m_aURL.getBindingUrl( ) ),
193 rUsername, rPassword, "", false, oauth2Data ));
194 if (!session)
195 ucbhelper::cancelCommandExecution(
196 ucb::IOErrorCode_INVALID_DEVICE,
197 uno::Sequence< uno::Any >( 0 ),
198 xEnv,
199 OUString( ) );
200 m_aRepositories = session->getRepositories( );
202 catch (const libcmis::Exception& e)
204 SAL_INFO( "ucb.ucp.cmis", "Error getting repositories: " << e.what() );
207 else
209 // Throw user cancelled exception
210 ucbhelper::cancelCommandExecution(
211 ucb::IOErrorCode_ABORT,
212 uno::Sequence< uno::Any >( 0 ),
213 xEnv,
214 OUString( "Authentication cancelled" ) );
219 libcmis::RepositoryPtr RepoContent::getRepository( const uno::Reference< ucb::XCommandEnvironment > & xEnv )
221 // Ensure we have the repositories extracted
222 getRepositories( xEnv );
224 libcmis::RepositoryPtr repo;
226 if ( !m_sRepositoryId.isEmpty() )
228 for ( vector< libcmis::RepositoryPtr >::iterator it = m_aRepositories.begin( );
229 it != m_aRepositories.end( ) && NULL == repo.get( ); ++it )
231 if ( STD_TO_OUSTR( ( *it )->getId( ) ) == m_sRepositoryId )
232 repo = *it;
235 else
236 repo = m_aRepositories.front( );
237 return repo;
240 uno::Sequence< beans::Property > RepoContent::getProperties(
241 const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
243 static const beans::Property aGenericProperties[] =
245 beans::Property( OUString( "IsDocument" ),
246 -1, cppu::UnoType<bool>::get(),
247 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
248 beans::Property( OUString( "IsFolder" ),
249 -1, cppu::UnoType<bool>::get(),
250 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
251 beans::Property( OUString( "Title" ),
252 -1, cppu::UnoType<OUString>::get(),
253 beans::PropertyAttribute::BOUND ),
254 beans::Property( OUString( "IsReadOnly" ),
255 -1, cppu::UnoType<bool>::get(),
256 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
259 const int nProps = SAL_N_ELEMENTS(aGenericProperties);
260 return uno::Sequence< beans::Property > ( aGenericProperties, nProps );
263 uno::Sequence< ucb::CommandInfo > RepoContent::getCommands(
264 const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
266 static const ucb::CommandInfo aCommandInfoTable[] =
268 // Required commands
269 ucb::CommandInfo
270 ( OUString( "getCommandInfo" ),
271 -1, cppu::UnoType<void>::get() ),
272 ucb::CommandInfo
273 ( OUString( "getPropertySetInfo" ),
274 -1, cppu::UnoType<void>::get() ),
275 ucb::CommandInfo
276 ( OUString( "getPropertyValues" ),
277 -1, cppu::UnoType<uno::Sequence< beans::Property >>::get() ),
278 ucb::CommandInfo
279 ( OUString( "setPropertyValues" ),
280 -1, cppu::UnoType<uno::Sequence< beans::PropertyValue >>::get() ),
282 // Optional standard commands
283 ucb::CommandInfo
284 ( OUString( "open" ),
285 -1, cppu::UnoType<ucb::OpenCommandArgument2>::get() ),
288 const int nProps = SAL_N_ELEMENTS(aCommandInfoTable);
289 return uno::Sequence< ucb::CommandInfo >(aCommandInfoTable, nProps );
292 OUString RepoContent::getParentURL( )
294 OUString sRet;
296 SAL_INFO( "ucb.ucp.cmis", "RepoContent::getParentURL()" );
298 // TODO Implement me
300 return sRet;
303 XTYPEPROVIDER_COMMON_IMPL( RepoContent );
305 void SAL_CALL RepoContent::acquire() throw()
307 ContentImplHelper::acquire();
310 void SAL_CALL RepoContent::release() throw()
312 ContentImplHelper::release();
315 uno::Any SAL_CALL RepoContent::queryInterface( const uno::Type & rType ) throw ( uno::RuntimeException, std::exception )
317 return ContentImplHelper::queryInterface(rType);
320 OUString SAL_CALL RepoContent::getImplementationName() throw( uno::RuntimeException, std::exception )
322 return OUString("com.sun.star.comp.CmisRepoContent");
325 uno::Sequence< OUString > SAL_CALL RepoContent::getSupportedServiceNames()
326 throw( uno::RuntimeException, std::exception )
328 uno::Sequence< OUString > aSNS( 1 );
329 aSNS.getArray()[ 0 ] = "com.sun.star.ucb.Content";
330 return aSNS;
333 OUString SAL_CALL RepoContent::getContentType() throw( uno::RuntimeException, std::exception )
335 return OUString( CMIS_REPO_TYPE );
338 uno::Any SAL_CALL RepoContent::execute(
339 const ucb::Command& aCommand,
340 sal_Int32 /*CommandId*/,
341 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
342 throw( uno::Exception, ucb::CommandAbortedException, uno::RuntimeException, std::exception )
344 SAL_INFO( "ucb.ucp.cmis", "RepoContent::execute( ) - " << aCommand.Name );
346 uno::Any aRet;
348 if ( aCommand.Name == "getPropertyValues" )
350 uno::Sequence< beans::Property > Properties;
351 if ( !( aCommand.Argument >>= Properties ) )
352 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
353 aRet <<= getPropertyValues( Properties, xEnv );
355 else if ( aCommand.Name == "getPropertySetInfo" )
356 aRet <<= getPropertySetInfo( xEnv, false );
357 else if ( aCommand.Name == "getCommandInfo" )
358 aRet <<= getCommandInfo( xEnv, false );
359 else if ( aCommand.Name == "open" )
361 ucb::OpenCommandArgument2 aOpenCommand;
362 if ( !( aCommand.Argument >>= aOpenCommand ) )
363 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
364 const ucb::OpenCommandArgument2& rOpenCommand = aOpenCommand;
366 getRepositories( xEnv );
367 uno::Reference< ucb::XDynamicResultSet > xSet
368 = new DynamicResultSet(m_xContext, this, rOpenCommand, xEnv );
369 aRet <<= xSet;
371 else
373 SAL_INFO( "ucb.ucp.cmis", "Command not allowed" );
376 return aRet;
379 void SAL_CALL RepoContent::abort( sal_Int32 /*CommandId*/ ) throw( uno::RuntimeException, std::exception )
381 SAL_INFO( "ucb.ucp.cmis", "TODO - RepoContent::abort()" );
382 // TODO Implement me
385 uno::Sequence< uno::Type > SAL_CALL RepoContent::getTypes() throw( uno::RuntimeException, std::exception )
387 static cppu::OTypeCollection aFolderCollection
388 (CPPU_TYPE_REF( lang::XTypeProvider ),
389 CPPU_TYPE_REF( lang::XServiceInfo ),
390 CPPU_TYPE_REF( lang::XComponent ),
391 CPPU_TYPE_REF( ucb::XContent ),
392 CPPU_TYPE_REF( ucb::XCommandProcessor ),
393 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
394 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
395 CPPU_TYPE_REF( beans::XPropertyContainer ),
396 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
397 CPPU_TYPE_REF( container::XChild ) );
398 return aFolderCollection.getTypes();
401 list< uno::Reference< ucb::XContent > > RepoContent::getChildren( )
403 list< uno::Reference< ucb::XContent > > result;
405 // TODO Cache the results somehow
406 SAL_INFO( "ucb.ucp.cmis", "RepoContent::getChildren" );
408 if ( m_sRepositoryId.isEmpty( ) )
410 for ( vector< libcmis::RepositoryPtr >::iterator it = m_aRepositories.begin( );
411 it != m_aRepositories.end(); ++it )
413 URL aUrl( m_aURL );
414 aUrl.setObjectPath( STD_TO_OUSTR( ( *it )->getId( ) ) );
416 uno::Reference< ucb::XContentIdentifier > xId = new ucbhelper::ContentIdentifier( aUrl.asString( ) );
417 uno::Reference< ucb::XContent > xContent = new RepoContent( m_xContext, m_pProvider, xId, m_aRepositories );
419 result.push_back( xContent );
422 else
424 // Return the repository root as child
425 OUString sUrl;
426 OUString sEncodedBinding = rtl::Uri::encode(
427 m_aURL.getBindingUrl( ) + "#" + m_sRepositoryId,
428 rtl_UriCharClassRelSegment,
429 rtl_UriEncodeKeepEscapes,
430 RTL_TEXTENCODING_UTF8 );
431 sUrl = "vnd.libreoffice.cmis://" + sEncodedBinding;
433 uno::Reference< ucb::XContentIdentifier > xId = new ucbhelper::ContentIdentifier( sUrl );
434 uno::Reference< ucb::XContent > xContent = new Content( m_xContext, m_pProvider, xId );
436 result.push_back( xContent );
438 return result;
442 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */