Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * Version: MPL 1.1 / GPLv3+ / LGPLv3+
4 : : *
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/
9 : : *
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.
14 : : *
15 : : * Major Contributor(s):
16 : : * [ Copyright (C) 2011 SUSE <cbosdonnat@suse.com> (initial developer) ]
17 : : *
18 : : * All Rights Reserved.
19 : : *
20 : : * For minor contributions see the git repository.
21 : : *
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.
27 : : */
28 : :
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>
37 : :
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 : :
45 : : #include "auth_provider.hxx"
46 : : #include "cmis_content.hxx"
47 : : #include "cmis_provider.hxx"
48 : : #include "cmis_repo_content.hxx"
49 : : #include "cmis_resultset.hxx"
50 : :
51 : : #define OUSTR_TO_STDSTR(s) string( rtl::OUStringToOString( s, RTL_TEXTENCODING_UTF8 ).getStr() )
52 : : #define STD_TO_OUSTR( str ) rtl::OUString( str.c_str(), str.length( ), RTL_TEXTENCODING_UTF8 )
53 : :
54 : : using namespace com::sun::star;
55 : : using namespace std;
56 : :
57 : : namespace cmis
58 : : {
59 : 0 : RepoContent::RepoContent( const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
60 : : ContentProvider *pProvider, const uno::Reference< ucb::XContentIdentifier >& Identifier,
61 : : list< libcmis::RepositoryPtr > aRepos )
62 : : throw ( ucb::ContentCreationException )
63 : : : ContentImplHelper( rxSMgr, pProvider, Identifier ),
64 : : m_pProvider( pProvider ),
65 : 0 : m_aURL( Identifier->getContentIdentifier( ) ),
66 : : m_sRepositoryId( ),
67 : 0 : m_aRepositories( aRepos )
68 : : {
69 : : // Split the URL into bits
70 : 0 : rtl::OUString sURL = m_xIdentifier->getContentIdentifier( );
71 : : SAL_INFO( "cmisucp", "RepoContent::RepoContent() " << sURL );
72 : :
73 : 0 : m_sRepositoryId = m_aURL.getObjectPath( );
74 : 0 : if ( m_sRepositoryId[0] == '/' )
75 : 0 : m_sRepositoryId = m_sRepositoryId.copy( 1 );
76 : :
77 : 0 : }
78 : :
79 : 0 : RepoContent::~RepoContent()
80 : : {
81 : 0 : }
82 : :
83 : 0 : uno::Any RepoContent::getBadArgExcept()
84 : : {
85 : : return uno::makeAny( lang::IllegalArgumentException(
86 : : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Wrong argument type!")),
87 : 0 : static_cast< cppu::OWeakObject * >( this ), -1) );
88 : : }
89 : :
90 : 0 : uno::Reference< sdbc::XRow > RepoContent::getPropertyValues(
91 : : const uno::Sequence< beans::Property >& rProperties,
92 : : const uno::Reference< ucb::XCommandEnvironment >& xEnv )
93 : : {
94 : 0 : rtl::Reference< ::ucbhelper::PropertyValueSet > xRow = new ::ucbhelper::PropertyValueSet( m_xSMgr );
95 : :
96 : : sal_Int32 nProps;
97 : : const beans::Property* pProps;
98 : :
99 : 0 : nProps = rProperties.getLength();
100 : 0 : pProps = rProperties.getConstArray();
101 : :
102 : 0 : for( sal_Int32 n = 0; n < nProps; ++n )
103 : : {
104 : 0 : const beans::Property& rProp = pProps[ n ];
105 : :
106 : : try
107 : : {
108 : 0 : if ( rProp.Name == "IsDocument" )
109 : : {
110 : 0 : xRow->appendBoolean( rProp, sal_False );
111 : : }
112 : 0 : else if ( rProp.Name == "IsFolder" )
113 : : {
114 : 0 : xRow->appendBoolean( rProp, sal_True );
115 : : }
116 : 0 : else if ( rProp.Name == "Title" )
117 : : {
118 : 0 : xRow->appendString( rProp, STD_TO_OUSTR( getRepository( xEnv )->getName( ) ) );
119 : : }
120 : 0 : else if ( rProp.Name == "IsReadOnly" )
121 : : {
122 : 0 : xRow->appendBoolean( rProp, sal_True );
123 : : }
124 : : else
125 : : {
126 : 0 : xRow->appendVoid( rProp );
127 : : SAL_INFO( "cmisucp", "Looking for unsupported property " << rProp.Name );
128 : : }
129 : : }
130 : 0 : catch (const libcmis::Exception&)
131 : : {
132 : 0 : xRow->appendVoid( rProp );
133 : : }
134 : : }
135 : :
136 : 0 : return uno::Reference< sdbc::XRow >( xRow.get() );
137 : : }
138 : :
139 : 0 : void RepoContent::getRepositories( const uno::Reference< ucb::XCommandEnvironment > & xEnv )
140 : : {
141 : 0 : if ( m_aRepositories.size( ) == 0 )
142 : : {
143 : : // Get the auth credentials
144 : 0 : AuthProvider authProvider( xEnv, m_xIdentifier->getContentIdentifier( ), m_aURL.getBindingUrl( ) );
145 : :
146 : 0 : string rUsername = OUSTR_TO_STDSTR( m_aURL.getUsername( ) );
147 : 0 : string rPassword = OUSTR_TO_STDSTR( m_aURL.getPassword( ) );
148 : 0 : if ( authProvider.authenticationQuery( rUsername, rPassword ) )
149 : : {
150 : 0 : map< int, string > params = m_aURL.getSessionParams( );
151 : 0 : params[USERNAME] = rUsername;
152 : 0 : params[PASSWORD] = rPassword;
153 : :
154 : : try
155 : : {
156 : 0 : m_aRepositories = libcmis::SessionFactory::getRepositories( params );
157 : : }
158 : 0 : catch (const libcmis::Exception&)
159 : : {
160 : 0 : }
161 : : }
162 : : else
163 : : {
164 : : // Throw user cancelled exception
165 : : ucbhelper::cancelCommandExecution(
166 : : ucb::IOErrorCode_ABORT,
167 : : uno::Sequence< uno::Any >( 0 ),
168 : : xEnv,
169 : 0 : rtl::OUString::createFromAscii( "Authentication cancelled" ) );
170 : 0 : }
171 : : }
172 : 0 : }
173 : :
174 : 0 : libcmis::RepositoryPtr RepoContent::getRepository( const uno::Reference< ucb::XCommandEnvironment > & xEnv )
175 : : {
176 : : // Ensure we have the repositories extracted
177 : 0 : getRepositories( xEnv );
178 : :
179 : 0 : libcmis::RepositoryPtr repo;
180 : :
181 : 0 : if ( !m_sRepositoryId.isEmpty() )
182 : : {
183 : 0 : for ( list< libcmis::RepositoryPtr >::iterator it = m_aRepositories.begin( );
184 : 0 : it != m_aRepositories.end( ) && NULL == repo.get( ); ++it )
185 : : {
186 : 0 : if ( STD_TO_OUSTR( ( *it )->getId( ) ) == m_sRepositoryId )
187 : 0 : repo = *it;
188 : : }
189 : : }
190 : 0 : return repo;
191 : : }
192 : :
193 : 0 : uno::Sequence< beans::Property > RepoContent::getProperties(
194 : : const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
195 : : {
196 : : static const beans::Property aGenericProperties[] =
197 : : {
198 : : beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
199 : 0 : -1, getCppuBooleanType(),
200 : : beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
201 : : beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
202 : 0 : -1, getCppuBooleanType(),
203 : : beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
204 : : beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
205 : 0 : -1, getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
206 : : beans::PropertyAttribute::BOUND ),
207 : : beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ),
208 : 0 : -1, getCppuBooleanType(),
209 : : beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
210 : 0 : };
211 : :
212 : 0 : const int nProps = SAL_N_ELEMENTS(aGenericProperties);
213 : 0 : return uno::Sequence< beans::Property > ( aGenericProperties, nProps );
214 : : }
215 : :
216 : 0 : uno::Sequence< ucb::CommandInfo > RepoContent::getCommands(
217 : : const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
218 : : {
219 : : static ucb::CommandInfo aCommandInfoTable[] =
220 : : {
221 : : // Required commands
222 : : ucb::CommandInfo
223 : : ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
224 : 0 : -1, getCppuVoidType() ),
225 : : ucb::CommandInfo
226 : : ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
227 : 0 : -1, getCppuVoidType() ),
228 : : ucb::CommandInfo
229 : : ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
230 : 0 : -1, getCppuType( static_cast<uno::Sequence< beans::Property > * >( 0 ) ) ),
231 : : ucb::CommandInfo
232 : : ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
233 : 0 : -1, getCppuType( static_cast<uno::Sequence< beans::PropertyValue > * >( 0 ) ) ),
234 : :
235 : : // Optional standard commands
236 : : ucb::CommandInfo
237 : : ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
238 : 0 : -1, getCppuType( static_cast<ucb::OpenCommandArgument2 * >( 0 ) ) ),
239 : 0 : };
240 : :
241 : 0 : const int nProps = SAL_N_ELEMENTS(aCommandInfoTable);
242 : 0 : return uno::Sequence< ucb::CommandInfo >(aCommandInfoTable, nProps );
243 : : }
244 : :
245 : 0 : ::rtl::OUString RepoContent::getParentURL( )
246 : : {
247 : 0 : rtl::OUString sRet;
248 : :
249 : : SAL_INFO( "cmisucp", "RepoContent::getParentURL()" );
250 : :
251 : : // TODO Implement me
252 : :
253 : 0 : return sRet;
254 : : }
255 : :
256 : 0 : XTYPEPROVIDER_COMMON_IMPL( RepoContent );
257 : :
258 : 0 : void SAL_CALL RepoContent::acquire() throw()
259 : : {
260 : 0 : ContentImplHelper::acquire();
261 : 0 : }
262 : :
263 : 0 : void SAL_CALL RepoContent::release() throw()
264 : : {
265 : 0 : ContentImplHelper::release();
266 : 0 : }
267 : :
268 : 0 : uno::Any SAL_CALL RepoContent::queryInterface( const uno::Type & rType ) throw ( uno::RuntimeException )
269 : : {
270 : 0 : return ContentImplHelper::queryInterface(rType);
271 : : }
272 : :
273 : 0 : rtl::OUString SAL_CALL RepoContent::getImplementationName() throw( uno::RuntimeException )
274 : : {
275 : 0 : return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.CmisRepoContent"));
276 : : }
277 : :
278 : 0 : uno::Sequence< rtl::OUString > SAL_CALL RepoContent::getSupportedServiceNames()
279 : : throw( uno::RuntimeException )
280 : : {
281 : 0 : uno::Sequence< rtl::OUString > aSNS( 1 );
282 : 0 : aSNS.getArray()[ 0 ] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.Content"));
283 : 0 : return aSNS;
284 : : }
285 : :
286 : 0 : rtl::OUString SAL_CALL RepoContent::getContentType() throw( uno::RuntimeException )
287 : : {
288 : 0 : return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CMIS_REPO_TYPE ) );
289 : : }
290 : :
291 : 0 : uno::Any SAL_CALL RepoContent::execute(
292 : : const ucb::Command& aCommand,
293 : : sal_Int32 /*CommandId*/,
294 : : const uno::Reference< ucb::XCommandEnvironment >& xEnv )
295 : : throw( uno::Exception, ucb::CommandAbortedException, uno::RuntimeException )
296 : : {
297 : : SAL_INFO( "cmisucp", "RepoContent::execute( ) - " << aCommand.Name );
298 : :
299 : 0 : uno::Any aRet;
300 : :
301 : 0 : if ( aCommand.Name == "getPropertyValues" )
302 : : {
303 : 0 : uno::Sequence< beans::Property > Properties;
304 : 0 : if ( !( aCommand.Argument >>= Properties ) )
305 : 0 : ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
306 : 0 : aRet <<= getPropertyValues( Properties, xEnv );
307 : : }
308 : 0 : else if ( aCommand.Name == "getPropertySetInfo" )
309 : 0 : aRet <<= getPropertySetInfo( xEnv, sal_False );
310 : 0 : else if ( aCommand.Name == "getCommandInfo" )
311 : 0 : aRet <<= getCommandInfo( xEnv, sal_False );
312 : 0 : else if ( aCommand.Name == "open" )
313 : : {
314 : 0 : ucb::OpenCommandArgument2 aOpenCommand;
315 : 0 : if ( !( aCommand.Argument >>= aOpenCommand ) )
316 : 0 : ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
317 : 0 : const ucb::OpenCommandArgument2& rOpenCommand = aOpenCommand;
318 : :
319 : 0 : getRepositories( xEnv );
320 : : uno::Reference< ucb::XDynamicResultSet > xSet
321 : 0 : = new DynamicResultSet(m_xSMgr, this, rOpenCommand, xEnv );
322 : 0 : aRet <<= xSet;
323 : : }
324 : : else
325 : : {
326 : : SAL_INFO( "cmisucp", "Command not allowed" );
327 : : }
328 : :
329 : 0 : return aRet;
330 : : }
331 : :
332 : 0 : void SAL_CALL RepoContent::abort( sal_Int32 /*CommandId*/ ) throw( uno::RuntimeException )
333 : : {
334 : : SAL_INFO( "cmisucp", "TODO - RepoContent::abort()" );
335 : : // TODO Implement me
336 : 0 : }
337 : :
338 : 0 : uno::Sequence< uno::Type > SAL_CALL RepoContent::getTypes() throw( uno::RuntimeException )
339 : : {
340 : : static cppu::OTypeCollection aFolderCollection
341 : 0 : (CPPU_TYPE_REF( lang::XTypeProvider ),
342 : 0 : CPPU_TYPE_REF( lang::XServiceInfo ),
343 : 0 : CPPU_TYPE_REF( lang::XComponent ),
344 : 0 : CPPU_TYPE_REF( ucb::XContent ),
345 : 0 : CPPU_TYPE_REF( ucb::XCommandProcessor ),
346 : 0 : CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
347 : 0 : CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
348 : 0 : CPPU_TYPE_REF( beans::XPropertyContainer ),
349 : 0 : CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
350 : 0 : CPPU_TYPE_REF( container::XChild ) );
351 : 0 : return aFolderCollection.getTypes();
352 : : }
353 : :
354 : 0 : list< uno::Reference< ucb::XContent > > RepoContent::getChildren( )
355 : : {
356 : 0 : list< uno::Reference< ucb::XContent > > result;
357 : :
358 : : // TODO Cache the results somehow
359 : : SAL_INFO( "cmisucp", "RepoContent::getChildren" );
360 : :
361 : 0 : if ( m_sRepositoryId.isEmpty( ) )
362 : : {
363 : 0 : for ( list< libcmis::RepositoryPtr >::iterator it = m_aRepositories.begin( );
364 : 0 : it != m_aRepositories.end(); ++it )
365 : : {
366 : 0 : URL aUrl( m_aURL );
367 : 0 : aUrl.setObjectPath( STD_TO_OUSTR( ( *it )->getId( ) ) );
368 : :
369 : 0 : uno::Reference< ucb::XContentIdentifier > xId = new ucbhelper::ContentIdentifier( aUrl.asString( ) );
370 : 0 : uno::Reference< ucb::XContent > xContent = new RepoContent( m_xSMgr, m_pProvider, xId, m_aRepositories );
371 : :
372 : 0 : result.push_back( xContent );
373 : 0 : }
374 : : }
375 : : else
376 : : {
377 : : // Return the repository root as child
378 : 0 : rtl::OUString sUrl;
379 : : rtl::OUString sEncodedBinding = rtl::Uri::encode(
380 : 0 : m_aURL.getBindingUrl( ) + "#" + m_sRepositoryId,
381 : : rtl_UriCharClassRelSegment,
382 : : rtl_UriEncodeKeepEscapes,
383 : 0 : RTL_TEXTENCODING_UTF8 );
384 : 0 : sUrl = "vnd.libreoffice.cmis+atom://" + sEncodedBinding;
385 : :
386 : 0 : uno::Reference< ucb::XContentIdentifier > xId = new ucbhelper::ContentIdentifier( sUrl );
387 : 0 : uno::Reference< ucb::XContent > xContent = new Content( m_xSMgr, m_pProvider, xId );
388 : :
389 : 0 : result.push_back( xContent );
390 : : }
391 : 0 : return result;
392 : : }
393 : 0 : }
394 : :
395 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|