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< uno::XComponentContext >& rxContext,
60 : ContentProvider *pProvider, const uno::Reference< ucb::XContentIdentifier >& Identifier,
61 : list< libcmis::RepositoryPtr > aRepos )
62 : throw ( ucb::ContentCreationException )
63 : : ContentImplHelper( rxContext, 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_xContext );
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.empty() )
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 : try
151 : {
152 : m_aRepositories = libcmis::SessionFactory::getRepositories(
153 0 : OUSTR_TO_STDSTR( m_aURL.getBindingUrl( ) ), rUsername, rPassword );
154 : }
155 0 : catch (const libcmis::Exception&)
156 : {
157 : }
158 : }
159 : else
160 : {
161 : // Throw user cancelled exception
162 : ucbhelper::cancelCommandExecution(
163 : ucb::IOErrorCode_ABORT,
164 : uno::Sequence< uno::Any >( 0 ),
165 : xEnv,
166 0 : rtl::OUString::createFromAscii( "Authentication cancelled" ) );
167 0 : }
168 : }
169 0 : }
170 :
171 0 : libcmis::RepositoryPtr RepoContent::getRepository( const uno::Reference< ucb::XCommandEnvironment > & xEnv )
172 : {
173 : // Ensure we have the repositories extracted
174 0 : getRepositories( xEnv );
175 :
176 0 : libcmis::RepositoryPtr repo;
177 :
178 0 : if ( !m_sRepositoryId.isEmpty() )
179 : {
180 0 : for ( list< libcmis::RepositoryPtr >::iterator it = m_aRepositories.begin( );
181 0 : it != m_aRepositories.end( ) && NULL == repo.get( ); ++it )
182 : {
183 0 : if ( STD_TO_OUSTR( ( *it )->getId( ) ) == m_sRepositoryId )
184 0 : repo = *it;
185 : }
186 : }
187 0 : return repo;
188 : }
189 :
190 0 : uno::Sequence< beans::Property > RepoContent::getProperties(
191 : const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
192 : {
193 : static const beans::Property aGenericProperties[] =
194 : {
195 : beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
196 0 : -1, getCppuBooleanType(),
197 : beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
198 : beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
199 0 : -1, getCppuBooleanType(),
200 : beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
201 : beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
202 0 : -1, getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
203 : beans::PropertyAttribute::BOUND ),
204 : beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ),
205 0 : -1, getCppuBooleanType(),
206 : beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
207 0 : };
208 :
209 0 : const int nProps = SAL_N_ELEMENTS(aGenericProperties);
210 0 : return uno::Sequence< beans::Property > ( aGenericProperties, nProps );
211 : }
212 :
213 0 : uno::Sequence< ucb::CommandInfo > RepoContent::getCommands(
214 : const uno::Reference< ucb::XCommandEnvironment > & /*xEnv*/ )
215 : {
216 : static ucb::CommandInfo aCommandInfoTable[] =
217 : {
218 : // Required commands
219 : ucb::CommandInfo
220 : ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
221 0 : -1, getCppuVoidType() ),
222 : ucb::CommandInfo
223 : ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
224 0 : -1, getCppuVoidType() ),
225 : ucb::CommandInfo
226 : ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
227 0 : -1, getCppuType( static_cast<uno::Sequence< beans::Property > * >( 0 ) ) ),
228 : ucb::CommandInfo
229 : ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
230 0 : -1, getCppuType( static_cast<uno::Sequence< beans::PropertyValue > * >( 0 ) ) ),
231 :
232 : // Optional standard commands
233 : ucb::CommandInfo
234 : ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
235 0 : -1, getCppuType( static_cast<ucb::OpenCommandArgument2 * >( 0 ) ) ),
236 0 : };
237 :
238 0 : const int nProps = SAL_N_ELEMENTS(aCommandInfoTable);
239 0 : return uno::Sequence< ucb::CommandInfo >(aCommandInfoTable, nProps );
240 : }
241 :
242 0 : ::rtl::OUString RepoContent::getParentURL( )
243 : {
244 0 : rtl::OUString sRet;
245 :
246 : SAL_INFO( "cmisucp", "RepoContent::getParentURL()" );
247 :
248 : // TODO Implement me
249 :
250 0 : return sRet;
251 : }
252 :
253 0 : XTYPEPROVIDER_COMMON_IMPL( RepoContent );
254 :
255 0 : void SAL_CALL RepoContent::acquire() throw()
256 : {
257 0 : ContentImplHelper::acquire();
258 0 : }
259 :
260 0 : void SAL_CALL RepoContent::release() throw()
261 : {
262 0 : ContentImplHelper::release();
263 0 : }
264 :
265 0 : uno::Any SAL_CALL RepoContent::queryInterface( const uno::Type & rType ) throw ( uno::RuntimeException )
266 : {
267 0 : return ContentImplHelper::queryInterface(rType);
268 : }
269 :
270 0 : rtl::OUString SAL_CALL RepoContent::getImplementationName() throw( uno::RuntimeException )
271 : {
272 0 : return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.CmisRepoContent"));
273 : }
274 :
275 0 : uno::Sequence< rtl::OUString > SAL_CALL RepoContent::getSupportedServiceNames()
276 : throw( uno::RuntimeException )
277 : {
278 0 : uno::Sequence< rtl::OUString > aSNS( 1 );
279 0 : aSNS.getArray()[ 0 ] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.Content"));
280 0 : return aSNS;
281 : }
282 :
283 0 : rtl::OUString SAL_CALL RepoContent::getContentType() throw( uno::RuntimeException )
284 : {
285 0 : return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CMIS_REPO_TYPE ) );
286 : }
287 :
288 0 : uno::Any SAL_CALL RepoContent::execute(
289 : const ucb::Command& aCommand,
290 : sal_Int32 /*CommandId*/,
291 : const uno::Reference< ucb::XCommandEnvironment >& xEnv )
292 : throw( uno::Exception, ucb::CommandAbortedException, uno::RuntimeException )
293 : {
294 : SAL_INFO( "cmisucp", "RepoContent::execute( ) - " << aCommand.Name );
295 :
296 0 : uno::Any aRet;
297 :
298 0 : if ( aCommand.Name == "getPropertyValues" )
299 : {
300 0 : uno::Sequence< beans::Property > Properties;
301 0 : if ( !( aCommand.Argument >>= Properties ) )
302 0 : ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
303 0 : aRet <<= getPropertyValues( Properties, xEnv );
304 : }
305 0 : else if ( aCommand.Name == "getPropertySetInfo" )
306 0 : aRet <<= getPropertySetInfo( xEnv, sal_False );
307 0 : else if ( aCommand.Name == "getCommandInfo" )
308 0 : aRet <<= getCommandInfo( xEnv, sal_False );
309 0 : else if ( aCommand.Name == "open" )
310 : {
311 0 : ucb::OpenCommandArgument2 aOpenCommand;
312 0 : if ( !( aCommand.Argument >>= aOpenCommand ) )
313 0 : ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
314 0 : const ucb::OpenCommandArgument2& rOpenCommand = aOpenCommand;
315 :
316 0 : getRepositories( xEnv );
317 : uno::Reference< ucb::XDynamicResultSet > xSet
318 0 : = new DynamicResultSet(m_xContext, this, rOpenCommand, xEnv );
319 0 : aRet <<= xSet;
320 : }
321 : else
322 : {
323 : SAL_INFO( "cmisucp", "Command not allowed" );
324 : }
325 :
326 0 : return aRet;
327 : }
328 :
329 0 : void SAL_CALL RepoContent::abort( sal_Int32 /*CommandId*/ ) throw( uno::RuntimeException )
330 : {
331 : SAL_INFO( "cmisucp", "TODO - RepoContent::abort()" );
332 : // TODO Implement me
333 0 : }
334 :
335 0 : uno::Sequence< uno::Type > SAL_CALL RepoContent::getTypes() throw( uno::RuntimeException )
336 : {
337 : static cppu::OTypeCollection aFolderCollection
338 0 : (CPPU_TYPE_REF( lang::XTypeProvider ),
339 0 : CPPU_TYPE_REF( lang::XServiceInfo ),
340 0 : CPPU_TYPE_REF( lang::XComponent ),
341 0 : CPPU_TYPE_REF( ucb::XContent ),
342 0 : CPPU_TYPE_REF( ucb::XCommandProcessor ),
343 0 : CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
344 0 : CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
345 0 : CPPU_TYPE_REF( beans::XPropertyContainer ),
346 0 : CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
347 0 : CPPU_TYPE_REF( container::XChild ) );
348 0 : return aFolderCollection.getTypes();
349 : }
350 :
351 0 : list< uno::Reference< ucb::XContent > > RepoContent::getChildren( )
352 : {
353 0 : list< uno::Reference< ucb::XContent > > result;
354 :
355 : // TODO Cache the results somehow
356 : SAL_INFO( "cmisucp", "RepoContent::getChildren" );
357 :
358 0 : if ( m_sRepositoryId.isEmpty( ) )
359 : {
360 0 : for ( list< libcmis::RepositoryPtr >::iterator it = m_aRepositories.begin( );
361 0 : it != m_aRepositories.end(); ++it )
362 : {
363 0 : URL aUrl( m_aURL );
364 0 : aUrl.setObjectPath( STD_TO_OUSTR( ( *it )->getId( ) ) );
365 :
366 0 : uno::Reference< ucb::XContentIdentifier > xId = new ucbhelper::ContentIdentifier( aUrl.asString( ) );
367 0 : uno::Reference< ucb::XContent > xContent = new RepoContent( m_xContext, m_pProvider, xId, m_aRepositories );
368 :
369 0 : result.push_back( xContent );
370 0 : }
371 : }
372 : else
373 : {
374 : // Return the repository root as child
375 0 : rtl::OUString sUrl;
376 : rtl::OUString sEncodedBinding = rtl::Uri::encode(
377 0 : m_aURL.getBindingUrl( ) + "#" + m_sRepositoryId,
378 : rtl_UriCharClassRelSegment,
379 : rtl_UriEncodeKeepEscapes,
380 0 : RTL_TEXTENCODING_UTF8 );
381 0 : sUrl = "vnd.libreoffice.cmis://" + sEncodedBinding;
382 :
383 0 : uno::Reference< ucb::XContentIdentifier > xId = new ucbhelper::ContentIdentifier( sUrl );
384 0 : uno::Reference< ucb::XContent > xContent = new Content( m_xContext, m_pProvider, xId );
385 :
386 0 : result.push_back( xContent );
387 : }
388 0 : return result;
389 : }
390 0 : }
391 :
392 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|