fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / ucb / source / ucp / tdoc / tdoc_provider.cxx
blobf0ed1286602b53a7c99dfc6472dd4b628a2a83d9
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 .
21 /**************************************************************************
22 TODO
23 **************************************************************************
25 *************************************************************************/
27 #include "rtl/ustrbuf.hxx"
28 #include <osl/diagnose.h>
30 #include "com/sun/star/container/XNameAccess.hpp"
31 #include "com/sun/star/embed/XStorage.hpp"
33 #include "comphelper/processfactory.hxx"
34 #include "ucbhelper/contentidentifier.hxx"
36 #include "tdoc_provider.hxx"
37 #include "tdoc_content.hxx"
38 #include "tdoc_uri.hxx"
39 #include "tdoc_docmgr.hxx"
40 #include "tdoc_storage.hxx"
42 using namespace com::sun::star;
43 using namespace tdoc_ucp;
48 // ContentProvider Implementation.
53 ContentProvider::ContentProvider(
54 const uno::Reference< uno::XComponentContext >& rxContext )
55 : ::ucbhelper::ContentProviderImplHelper( rxContext ),
56 m_xDocsMgr( new OfficeDocumentsManager( rxContext, this ) ),
57 m_xStgElemFac( new StorageElementFactory( rxContext, m_xDocsMgr ) )
62 // virtual
63 ContentProvider::~ContentProvider()
65 if ( m_xDocsMgr.is() )
66 m_xDocsMgr->destroy();
71 // XInterface methods.
72 void SAL_CALL ContentProvider::acquire()
73 throw()
75 OWeakObject::acquire();
78 void SAL_CALL ContentProvider::release()
79 throw()
81 OWeakObject::release();
84 css::uno::Any SAL_CALL ContentProvider::queryInterface( const css::uno::Type & rType )
85 throw( css::uno::RuntimeException, std::exception )
87 css::uno::Any aRet = cppu::queryInterface( rType,
88 (static_cast< lang::XTypeProvider* >(this)),
89 (static_cast< lang::XServiceInfo* >(this)),
90 (static_cast< ucb::XContentProvider* >(this)),
91 (static_cast< frame::XTransientDocumentsDocumentContentFactory* >(this))
93 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
96 // XTypeProvider methods.
100 XTYPEPROVIDER_IMPL_4( ContentProvider,
101 lang::XTypeProvider,
102 lang::XServiceInfo,
103 ucb::XContentProvider,
104 frame::XTransientDocumentsDocumentContentFactory );
108 // XServiceInfo methods.
112 XSERVICEINFO_IMPL_1_CTX(
113 ContentProvider,
114 OUString( "com.sun.star.comp.ucb.TransientDocumentsContentProvider" ),
115 TDOC_CONTENT_PROVIDER_SERVICE_NAME );
119 // Service factory implementation.
123 ONE_INSTANCE_SERVICE_FACTORY_IMPL( ContentProvider );
127 // XContentProvider methods.
131 // virtual
132 uno::Reference< ucb::XContent > SAL_CALL
133 ContentProvider::queryContent(
134 const uno::Reference< ucb::XContentIdentifier >& Identifier )
135 throw( ucb::IllegalIdentifierException, uno::RuntimeException, std::exception )
137 Uri aUri( Identifier->getContentIdentifier() );
138 if ( !aUri.isValid() )
139 throw ucb::IllegalIdentifierException(
140 OUString( "Invalid URL!" ),
141 Identifier );
143 // Normalize URI.
144 uno::Reference< ucb::XContentIdentifier > xCanonicId
145 = new ::ucbhelper::ContentIdentifier( aUri.getUri() );
147 osl::MutexGuard aGuard( m_aMutex );
149 // Check, if a content with given id already exists...
150 uno::Reference< ucb::XContent > xContent
151 = queryExistingContent( xCanonicId ).get();
153 if ( !xContent.is() )
155 // Create a new content.
156 xContent = Content::create( m_xContext, this, xCanonicId );
157 registerNewContent( xContent );
160 return xContent;
165 // XTransientDocumentsDocumentContentFactory methods.
169 // virtual
170 uno::Reference< ucb::XContent > SAL_CALL
171 ContentProvider::createDocumentContent(
172 const uno::Reference< frame::XModel >& Model )
173 throw ( lang::IllegalArgumentException, uno::RuntimeException, std::exception )
175 // model -> id -> content identifier -> queryContent
176 if ( m_xDocsMgr.is() )
178 OUString aDocId = tdoc_ucp::OfficeDocumentsManager::queryDocumentId( Model );
179 if ( !aDocId.isEmpty() )
181 OUStringBuffer aBuffer;
182 aBuffer.appendAscii( TDOC_URL_SCHEME ":/" );
183 aBuffer.append( aDocId );
185 uno::Reference< ucb::XContentIdentifier > xId
186 = new ::ucbhelper::ContentIdentifier( aBuffer.makeStringAndClear() );
188 osl::MutexGuard aGuard( m_aMutex );
190 // Check, if a content with given id already exists...
191 uno::Reference< ucb::XContent > xContent
192 = queryExistingContent( xId ).get();
194 if ( !xContent.is() )
196 // Create a new content.
197 xContent = Content::create( m_xContext, this, xId );
200 if ( xContent.is() )
201 return xContent;
203 // no content.
204 throw lang::IllegalArgumentException(
205 OUString(
206 "Illegal Content Identifier!" ),
207 static_cast< cppu::OWeakObject * >( this ),
208 1 );
210 else
212 throw lang::IllegalArgumentException(
213 OUString(
214 "Unable to obtain document id from model!" ),
215 static_cast< cppu::OWeakObject * >( this ),
216 1 );
219 else
221 throw lang::IllegalArgumentException(
222 OUString(
223 "No Document Manager!" ),
224 static_cast< cppu::OWeakObject * >( this ),
225 1 );
231 // interface OfficeDocumentsEventListener
235 // virtual
236 void ContentProvider::notifyDocumentClosed( const OUString & rDocId )
238 osl::MutexGuard aGuard( getContentListMutex() );
240 ::ucbhelper::ContentRefList aAllContents;
241 queryExistingContents( aAllContents );
243 ::ucbhelper::ContentRefList::const_iterator it = aAllContents.begin();
244 ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
246 // Notify all content objects related to the closed doc.
248 bool bFoundDocumentContent = false;
249 rtl::Reference< Content > xRoot;
251 while ( it != end )
253 Uri aUri( (*it)->getIdentifier()->getContentIdentifier() );
254 OSL_ENSURE( aUri.isValid(),
255 "ContentProvider::notifyDocumentClosed - Invalid URI!" );
257 if ( !bFoundDocumentContent )
259 if ( aUri.isRoot() )
261 xRoot = static_cast< Content * >( (*it).get() );
263 else if ( aUri.isDocument() )
265 if ( aUri.getDocumentId() == rDocId )
267 bFoundDocumentContent = true;
269 // document content will notify removal of child itself;
270 // no need for the root to propagate this.
271 xRoot.clear();
276 if ( aUri.getDocumentId() == rDocId )
278 // Inform content.
279 rtl::Reference< Content > xContent
280 = static_cast< Content * >( (*it).get() );
282 xContent->notifyDocumentClosed();
285 ++it;
288 if ( xRoot.is() )
290 // No document content found for rDocId but root content
291 // instantiated. Root content must announce document removal
292 // to content event listeners.
293 xRoot->notifyChildRemoved( rDocId );
298 // virtual
299 void ContentProvider::notifyDocumentOpened( const OUString & rDocId )
301 osl::MutexGuard aGuard( getContentListMutex() );
303 ::ucbhelper::ContentRefList aAllContents;
304 queryExistingContents( aAllContents );
306 ::ucbhelper::ContentRefList::const_iterator it = aAllContents.begin();
307 ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
309 // Find root content. If instantiated let it propagate document insertion.
311 while ( it != end )
313 Uri aUri( (*it)->getIdentifier()->getContentIdentifier() );
314 OSL_ENSURE( aUri.isValid(),
315 "ContentProvider::notifyDocumentOpened - Invalid URI!" );
317 if ( aUri.isRoot() )
319 rtl::Reference< Content > xRoot
320 = static_cast< Content * >( (*it).get() );
321 xRoot->notifyChildInserted( rDocId );
323 // Done.
324 break;
327 ++it;
333 // Non-UNO
337 uno::Reference< embed::XStorage >
338 ContentProvider::queryStorage( const OUString & rUri,
339 StorageAccessMode eMode ) const
341 if ( m_xStgElemFac.is() )
345 return m_xStgElemFac->createStorage( rUri, eMode );
347 catch ( embed::InvalidStorageException const & )
349 OSL_FAIL( "Caught InvalidStorageException!" );
351 catch ( lang::IllegalArgumentException const & )
353 OSL_FAIL( "Caught IllegalArgumentException!" );
355 catch ( io::IOException const & )
357 // Okay to happen, for instance when the storage does not exist.
358 //OSL_ENSURE( false, "Caught IOException!" );
360 catch ( embed::StorageWrappedTargetException const & )
362 OSL_FAIL( "Caught embed::StorageWrappedTargetException!" );
365 return uno::Reference< embed::XStorage >();
369 uno::Reference< embed::XStorage >
370 ContentProvider::queryStorageClone( const OUString & rUri ) const
372 if ( m_xStgElemFac.is() )
376 Uri aUri( rUri );
377 uno::Reference< embed::XStorage > xParentStorage
378 = m_xStgElemFac->createStorage( aUri.getParentUri(), READ );
379 uno::Reference< embed::XStorage > xStorage
380 = m_xStgElemFac->createTemporaryStorage();
382 xParentStorage->copyStorageElementLastCommitTo(
383 aUri.getDecodedName(), xStorage );
384 return xStorage;
386 catch ( embed::InvalidStorageException const & )
388 OSL_FAIL( "Caught InvalidStorageException!" );
390 catch ( lang::IllegalArgumentException const & )
392 OSL_FAIL( "Caught IllegalArgumentException!" );
394 catch ( io::IOException const & )
396 // Okay to happen, for instance when the storage does not exist.
397 //OSL_ENSURE( false, "Caught IOException!" );
399 catch ( embed::StorageWrappedTargetException const & )
401 OSL_FAIL( "Caught embed::StorageWrappedTargetException!" );
405 return uno::Reference< embed::XStorage >();
409 uno::Reference< io::XInputStream >
410 ContentProvider::queryInputStream( const OUString & rUri,
411 const OUString & rPassword ) const
412 throw ( packages::WrongPasswordException, css::uno::RuntimeException )
414 if ( m_xStgElemFac.is() )
418 return m_xStgElemFac->createInputStream( rUri, rPassword );
420 catch ( embed::InvalidStorageException const & )
422 OSL_FAIL( "Caught InvalidStorageException!" );
424 catch ( lang::IllegalArgumentException const & )
426 OSL_FAIL( "Caught IllegalArgumentException!" );
428 catch ( io::IOException const & )
430 OSL_FAIL( "Caught IOException!" );
432 catch ( embed::StorageWrappedTargetException const & )
434 OSL_FAIL( "Caught embed::StorageWrappedTargetException!" );
436 // catch ( packages::WrongPasswordException const & )
437 // {
438 // // the key provided is wrong; rethrow; to be handled by caller.
439 // throw;
440 // }
442 return uno::Reference< io::XInputStream >();
446 uno::Reference< io::XOutputStream >
447 ContentProvider::queryOutputStream( const OUString & rUri,
448 const OUString & rPassword,
449 bool bTruncate ) const
450 throw ( packages::WrongPasswordException,
451 uno::RuntimeException )
453 if ( m_xStgElemFac.is() )
457 return
458 m_xStgElemFac->createOutputStream( rUri, rPassword, bTruncate );
460 catch ( embed::InvalidStorageException const & )
462 OSL_FAIL( "Caught InvalidStorageException!" );
464 catch ( lang::IllegalArgumentException const & )
466 OSL_FAIL( "Caught IllegalArgumentException!" );
468 catch ( io::IOException const & )
470 // Okay to happen, for instance when the storage does not exist.
471 //OSL_ENSURE( false, "Caught IOException!" );
473 catch ( embed::StorageWrappedTargetException const & )
475 OSL_FAIL( "Caught embed::StorageWrappedTargetException!" );
477 // catch ( packages::WrongPasswordException const & )
478 // {
479 // // the key provided is wrong; rethrow; to be handled by caller.
480 // throw;
481 // }
483 return uno::Reference< io::XOutputStream >();
487 uno::Reference< io::XStream >
488 ContentProvider::queryStream( const OUString & rUri,
489 const OUString & rPassword,
490 bool bTruncate ) const
491 throw ( packages::WrongPasswordException, uno::RuntimeException )
493 if ( m_xStgElemFac.is() )
497 return m_xStgElemFac->createStream( rUri, rPassword, bTruncate );
499 catch ( embed::InvalidStorageException const & )
501 OSL_FAIL( "Caught InvalidStorageException!" );
503 catch ( lang::IllegalArgumentException const & )
505 OSL_FAIL( "Caught IllegalArgumentException!" );
507 catch ( io::IOException const & )
509 // Okay to happen, for instance when the storage does not exist.
510 //OSL_ENSURE( false, "Caught IOException!" );
512 catch ( embed::StorageWrappedTargetException const & )
514 OSL_FAIL( "Caught embed::StorageWrappedTargetException!" );
516 // catch ( packages::WrongPasswordException const & )
517 // {
518 // // the key provided is wrong; rethrow; to be handled by caller.
519 // throw;
520 // }
522 return uno::Reference< io::XStream >();
526 bool ContentProvider::queryNamesOfChildren(
527 const OUString & rUri, uno::Sequence< OUString > & rNames ) const
529 Uri aUri( rUri );
530 if ( aUri.isRoot() )
532 // special handling for root, which has no storage, but children.
533 if ( m_xDocsMgr.is() )
535 rNames = m_xDocsMgr->queryDocuments();
536 return true;
539 else
541 if ( m_xStgElemFac.is() )
545 uno::Reference< embed::XStorage > xStorage
546 = m_xStgElemFac->createStorage( rUri, READ );
548 OSL_ENSURE( xStorage.is(), "Got no Storage!" );
550 if ( xStorage.is() )
552 uno::Reference< container::XNameAccess > xNA(
553 xStorage, uno::UNO_QUERY );
555 OSL_ENSURE( xNA.is(), "Got no css.container.XNameAccess!" );
556 if ( xNA.is() )
558 rNames = xNA->getElementNames();
559 return true;
563 catch ( embed::InvalidStorageException const & )
565 OSL_FAIL( "Caught InvalidStorageException!" );
567 catch ( lang::IllegalArgumentException const & )
569 OSL_FAIL( "Caught IllegalArgumentException!" );
571 catch ( io::IOException const & )
573 // Okay to happen, for instance if the storage does not exist.
574 //OSL_ENSURE( false, "Caught IOException!" );
576 catch ( embed::StorageWrappedTargetException const & )
578 OSL_FAIL( "Caught embed::StorageWrappedTargetException!" );
582 return false;
586 OUString
587 ContentProvider::queryStorageTitle( const OUString & rUri ) const
589 OUString aTitle;
591 Uri aUri( rUri );
592 if ( aUri.isRoot() )
594 // always empty.
595 aTitle.clear();
597 else if ( aUri.isDocument() )
599 // for documents, title shall not be derived from URL. It shall
600 // be somethimg more 'speaking' than just the document UID.
601 if ( m_xDocsMgr.is() )
602 aTitle = m_xDocsMgr->queryStorageTitle( aUri.getDocumentId() );
604 else
606 // derive title from URL
607 aTitle = aUri.getDecodedName();
610 OSL_ENSURE( !aTitle.isEmpty() || aUri.isRoot(),
611 "ContentProvider::queryStorageTitle - empty title!" );
612 return aTitle;
616 uno::Reference< frame::XModel >
617 ContentProvider::queryDocumentModel( const OUString & rUri ) const
619 uno::Reference< frame::XModel > xModel;
621 if ( m_xDocsMgr.is() )
623 Uri aUri( rUri );
624 xModel = m_xDocsMgr->queryDocumentModel( aUri.getDocumentId() );
627 OSL_ENSURE( xModel.is(),
628 "ContentProvider::queryDocumentModel - no model!" );
629 return xModel;
632 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */