Version 4.0.2.1, tag libreoffice-4.0.2.1
[LibreOffice.git] / ucb / source / ucp / cmis / cmis_repo_content.cxx
blobb76514c0b79a0e6ae1097f5f73ec8c39a02329ae
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * Version: MPL 1.1 / GPLv3+ / LGPLv3+
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License or as specified alternatively below. You may obtain a copy of
8 * the License at http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * Major Contributor(s):
16 * [ Copyright (C) 2011 SUSE <cbosdonnat@suse.com> (initial developer) ]
18 * All Rights Reserved.
20 * For minor contributions see the git repository.
22 * Alternatively, the contents of this file may be used under the terms of
23 * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
24 * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
25 * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
26 * instead of those above.
29 #include <com/sun/star/beans/PropertyAttribute.hpp>
30 #include <com/sun/star/beans/PropertyValue.hpp>
31 #include <com/sun/star/beans/XPropertySetInfo.hpp>
32 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
33 #include <com/sun/star/task/XInteractionHandler.hpp>
34 #include <com/sun/star/ucb/XCommandInfo.hpp>
35 #include <com/sun/star/ucb/XDynamicResultSet.hpp>
36 #include <com/sun/star/ucb/XProgressHandler.hpp>
38 #include <comphelper/processfactory.hxx>
39 #include <rtl/uri.hxx>
40 #include <ucbhelper/cancelcommandexecution.hxx>
41 #include <ucbhelper/commandenvironment.hxx>
42 #include <ucbhelper/contentidentifier.hxx>
43 #include <ucbhelper/propertyvalueset.hxx>
44 #include <ucbhelper/proxydecider.hxx>
46 #include "auth_provider.hxx"
47 #include "cmis_content.hxx"
48 #include "cmis_provider.hxx"
49 #include "cmis_repo_content.hxx"
50 #include "cmis_resultset.hxx"
52 #define OUSTR_TO_STDSTR(s) string( rtl::OUStringToOString( s, RTL_TEXTENCODING_UTF8 ).getStr() )
53 #define STD_TO_OUSTR( str ) rtl::OUString( str.c_str(), str.length( ), RTL_TEXTENCODING_UTF8 )
55 using namespace com::sun::star;
56 using namespace std;
58 namespace cmis
60 RepoContent::RepoContent( const uno::Reference< uno::XComponentContext >& rxContext,
61 ContentProvider *pProvider, const uno::Reference< ucb::XContentIdentifier >& Identifier,
62 list< libcmis::RepositoryPtr > aRepos )
63 throw ( ucb::ContentCreationException )
64 : ContentImplHelper( rxContext, pProvider, Identifier ),
65 m_pProvider( pProvider ),
66 m_aURL( Identifier->getContentIdentifier( ) ),
67 m_sRepositoryId( ),
68 m_aRepositories( aRepos )
70 // Split the URL into bits
71 rtl::OUString sURL = m_xIdentifier->getContentIdentifier( );
72 SAL_INFO( "cmisucp", "RepoContent::RepoContent() " << sURL );
74 m_sRepositoryId = m_aURL.getObjectPath( );
75 if ( m_sRepositoryId[0] == '/' )
76 m_sRepositoryId = m_sRepositoryId.copy( 1 );
80 RepoContent::~RepoContent()
84 uno::Any RepoContent::getBadArgExcept()
86 return uno::makeAny( lang::IllegalArgumentException(
87 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Wrong argument type!")),
88 static_cast< cppu::OWeakObject * >( this ), -1) );
91 uno::Reference< sdbc::XRow > RepoContent::getPropertyValues(
92 const uno::Sequence< beans::Property >& rProperties,
93 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
95 rtl::Reference< ::ucbhelper::PropertyValueSet > xRow = new ::ucbhelper::PropertyValueSet( m_xContext );
97 sal_Int32 nProps;
98 const beans::Property* pProps;
100 nProps = rProperties.getLength();
101 pProps = rProperties.getConstArray();
103 for( sal_Int32 n = 0; n < nProps; ++n )
105 const beans::Property& rProp = pProps[ n ];
109 if ( rProp.Name == "IsDocument" )
111 xRow->appendBoolean( rProp, sal_False );
113 else if ( rProp.Name == "IsFolder" )
115 xRow->appendBoolean( rProp, sal_True );
117 else if ( rProp.Name == "Title" )
119 xRow->appendString( rProp, STD_TO_OUSTR( getRepository( xEnv )->getName( ) ) );
121 else if ( rProp.Name == "IsReadOnly" )
123 xRow->appendBoolean( rProp, sal_True );
125 else
127 xRow->appendVoid( rProp );
128 SAL_INFO( "cmisucp", "Looking for unsupported property " << rProp.Name );
131 catch (const libcmis::Exception&)
133 xRow->appendVoid( rProp );
137 return uno::Reference< sdbc::XRow >( xRow.get() );
140 void RepoContent::getRepositories( const uno::Reference< ucb::XCommandEnvironment > & xEnv )
142 // Set the proxy if needed. We are doing that all times as the proxy data shouldn't be cached.
143 ucbhelper::InternetProxyDecider aProxyDecider( m_xContext );
144 INetURLObject aBindingUrl( m_aURL.getBindingUrl( ) );
145 const ucbhelper::InternetProxyServer& rProxy = aProxyDecider.getProxy(
146 INetURLObject::GetScheme( aBindingUrl.GetProtocol( ) ), aBindingUrl.GetHost(), aBindingUrl.GetPort() );
147 rtl::OUString sProxy = rProxy.aName;
148 if ( rProxy.nPort > 0 )
149 sProxy += ":" + rtl::OUString::valueOf( rProxy.nPort );
150 libcmis::SessionFactory::setProxySettings( OUSTR_TO_STDSTR( sProxy ), string(), string(), string() );
152 if ( m_aRepositories.empty() )
154 // Get the auth credentials
155 AuthProvider authProvider( xEnv, m_xIdentifier->getContentIdentifier( ), m_aURL.getBindingUrl( ) );
157 string rUsername = OUSTR_TO_STDSTR( m_aURL.getUsername( ) );
158 string rPassword = OUSTR_TO_STDSTR( m_aURL.getPassword( ) );
159 if ( authProvider.authenticationQuery( rUsername, rPassword ) )
163 m_aRepositories = libcmis::SessionFactory::getRepositories(
164 OUSTR_TO_STDSTR( m_aURL.getBindingUrl( ) ), rUsername, rPassword );
166 catch (const libcmis::Exception&)
170 else
172 // Throw user cancelled exception
173 ucbhelper::cancelCommandExecution(
174 ucb::IOErrorCode_ABORT,
175 uno::Sequence< uno::Any >( 0 ),
176 xEnv,
177 rtl::OUString::createFromAscii( "Authentication cancelled" ) );
182 libcmis::RepositoryPtr RepoContent::getRepository( const uno::Reference< ucb::XCommandEnvironment > & xEnv )
184 // Ensure we have the repositories extracted
185 getRepositories( xEnv );
187 libcmis::RepositoryPtr repo;
189 if ( !m_sRepositoryId.isEmpty() )
191 for ( list< libcmis::RepositoryPtr >::iterator it = m_aRepositories.begin( );
192 it != m_aRepositories.end( ) && NULL == repo.get( ); ++it )
194 if ( STD_TO_OUSTR( ( *it )->getId( ) ) == m_sRepositoryId )
195 repo = *it;
198 return repo;
201 uno::Sequence< beans::Property > RepoContent::getProperties(
202 const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
204 static const beans::Property aGenericProperties[] =
206 beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
207 -1, getCppuBooleanType(),
208 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
209 beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
210 -1, getCppuBooleanType(),
211 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
212 beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
213 -1, getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
214 beans::PropertyAttribute::BOUND ),
215 beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ),
216 -1, getCppuBooleanType(),
217 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
220 const int nProps = SAL_N_ELEMENTS(aGenericProperties);
221 return uno::Sequence< beans::Property > ( aGenericProperties, nProps );
224 uno::Sequence< ucb::CommandInfo > RepoContent::getCommands(
225 const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
227 static ucb::CommandInfo aCommandInfoTable[] =
229 // Required commands
230 ucb::CommandInfo
231 ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
232 -1, getCppuVoidType() ),
233 ucb::CommandInfo
234 ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
235 -1, getCppuVoidType() ),
236 ucb::CommandInfo
237 ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
238 -1, getCppuType( static_cast<uno::Sequence< beans::Property > * >( 0 ) ) ),
239 ucb::CommandInfo
240 ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
241 -1, getCppuType( static_cast<uno::Sequence< beans::PropertyValue > * >( 0 ) ) ),
243 // Optional standard commands
244 ucb::CommandInfo
245 ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
246 -1, getCppuType( static_cast<ucb::OpenCommandArgument2 * >( 0 ) ) ),
249 const int nProps = SAL_N_ELEMENTS(aCommandInfoTable);
250 return uno::Sequence< ucb::CommandInfo >(aCommandInfoTable, nProps );
253 ::rtl::OUString RepoContent::getParentURL( )
255 rtl::OUString sRet;
257 SAL_INFO( "cmisucp", "RepoContent::getParentURL()" );
259 // TODO Implement me
261 return sRet;
264 XTYPEPROVIDER_COMMON_IMPL( RepoContent );
266 void SAL_CALL RepoContent::acquire() throw()
268 ContentImplHelper::acquire();
271 void SAL_CALL RepoContent::release() throw()
273 ContentImplHelper::release();
276 uno::Any SAL_CALL RepoContent::queryInterface( const uno::Type & rType ) throw ( uno::RuntimeException )
278 return ContentImplHelper::queryInterface(rType);
281 rtl::OUString SAL_CALL RepoContent::getImplementationName() throw( uno::RuntimeException )
283 return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.CmisRepoContent"));
286 uno::Sequence< rtl::OUString > SAL_CALL RepoContent::getSupportedServiceNames()
287 throw( uno::RuntimeException )
289 uno::Sequence< rtl::OUString > aSNS( 1 );
290 aSNS.getArray()[ 0 ] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.Content"));
291 return aSNS;
294 rtl::OUString SAL_CALL RepoContent::getContentType() throw( uno::RuntimeException )
296 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CMIS_REPO_TYPE ) );
299 uno::Any SAL_CALL RepoContent::execute(
300 const ucb::Command& aCommand,
301 sal_Int32 /*CommandId*/,
302 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
303 throw( uno::Exception, ucb::CommandAbortedException, uno::RuntimeException )
305 SAL_INFO( "cmisucp", "RepoContent::execute( ) - " << aCommand.Name );
307 uno::Any aRet;
309 if ( aCommand.Name == "getPropertyValues" )
311 uno::Sequence< beans::Property > Properties;
312 if ( !( aCommand.Argument >>= Properties ) )
313 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
314 aRet <<= getPropertyValues( Properties, xEnv );
316 else if ( aCommand.Name == "getPropertySetInfo" )
317 aRet <<= getPropertySetInfo( xEnv, sal_False );
318 else if ( aCommand.Name == "getCommandInfo" )
319 aRet <<= getCommandInfo( xEnv, sal_False );
320 else if ( aCommand.Name == "open" )
322 ucb::OpenCommandArgument2 aOpenCommand;
323 if ( !( aCommand.Argument >>= aOpenCommand ) )
324 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
325 const ucb::OpenCommandArgument2& rOpenCommand = aOpenCommand;
327 getRepositories( xEnv );
328 uno::Reference< ucb::XDynamicResultSet > xSet
329 = new DynamicResultSet(m_xContext, this, rOpenCommand, xEnv );
330 aRet <<= xSet;
332 else
334 SAL_INFO( "cmisucp", "Command not allowed" );
337 return aRet;
340 void SAL_CALL RepoContent::abort( sal_Int32 /*CommandId*/ ) throw( uno::RuntimeException )
342 SAL_INFO( "cmisucp", "TODO - RepoContent::abort()" );
343 // TODO Implement me
346 uno::Sequence< uno::Type > SAL_CALL RepoContent::getTypes() throw( uno::RuntimeException )
348 static cppu::OTypeCollection aFolderCollection
349 (CPPU_TYPE_REF( lang::XTypeProvider ),
350 CPPU_TYPE_REF( lang::XServiceInfo ),
351 CPPU_TYPE_REF( lang::XComponent ),
352 CPPU_TYPE_REF( ucb::XContent ),
353 CPPU_TYPE_REF( ucb::XCommandProcessor ),
354 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
355 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
356 CPPU_TYPE_REF( beans::XPropertyContainer ),
357 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
358 CPPU_TYPE_REF( container::XChild ) );
359 return aFolderCollection.getTypes();
362 list< uno::Reference< ucb::XContent > > RepoContent::getChildren( )
364 list< uno::Reference< ucb::XContent > > result;
366 // TODO Cache the results somehow
367 SAL_INFO( "cmisucp", "RepoContent::getChildren" );
369 if ( m_sRepositoryId.isEmpty( ) )
371 for ( list< libcmis::RepositoryPtr >::iterator it = m_aRepositories.begin( );
372 it != m_aRepositories.end(); ++it )
374 URL aUrl( m_aURL );
375 aUrl.setObjectPath( STD_TO_OUSTR( ( *it )->getId( ) ) );
377 uno::Reference< ucb::XContentIdentifier > xId = new ucbhelper::ContentIdentifier( aUrl.asString( ) );
378 uno::Reference< ucb::XContent > xContent = new RepoContent( m_xContext, m_pProvider, xId, m_aRepositories );
380 result.push_back( xContent );
383 else
385 // Return the repository root as child
386 rtl::OUString sUrl;
387 rtl::OUString sEncodedBinding = rtl::Uri::encode(
388 m_aURL.getBindingUrl( ) + "#" + m_sRepositoryId,
389 rtl_UriCharClassRelSegment,
390 rtl_UriEncodeKeepEscapes,
391 RTL_TEXTENCODING_UTF8 );
392 sUrl = "vnd.libreoffice.cmis://" + sEncodedBinding;
394 uno::Reference< ucb::XContentIdentifier > xId = new ucbhelper::ContentIdentifier( sUrl );
395 uno::Reference< ucb::XContent > xContent = new Content( m_xContext, m_pProvider, xId );
397 result.push_back( xContent );
399 return result;
403 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */