Update ooo320-m1
[ooovba.git] / ucb / source / ucp / tdoc / tdoc_provider.cxx
blob684e4bb609ba0b83352de6f00b350117685e3440
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: tdoc_provider.cxx,v $
10 * $Revision: 1.11 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_ucb.hxx"
34 /**************************************************************************
35 TODO
36 **************************************************************************
38 *************************************************************************/
40 #include "rtl/ustrbuf.hxx"
42 #include "com/sun/star/container/XNameAccess.hpp"
43 #include "com/sun/star/embed/XStorage.hpp"
45 #include "ucbhelper/contentidentifier.hxx"
47 #include "tdoc_provider.hxx"
48 #include "tdoc_content.hxx"
49 #include "tdoc_uri.hxx"
50 #include "tdoc_docmgr.hxx"
51 #include "tdoc_storage.hxx"
53 using namespace com::sun::star;
54 using namespace tdoc_ucp;
56 //=========================================================================
57 //=========================================================================
59 // ContentProvider Implementation.
61 //=========================================================================
62 //=========================================================================
64 ContentProvider::ContentProvider(
65 const uno::Reference< lang::XMultiServiceFactory >& xSMgr )
66 : ::ucbhelper::ContentProviderImplHelper( xSMgr ),
67 m_xDocsMgr( new OfficeDocumentsManager( xSMgr, this ) ),
68 m_xStgElemFac( new StorageElementFactory( xSMgr, m_xDocsMgr ) )
72 //=========================================================================
73 // virtual
74 ContentProvider::~ContentProvider()
76 if ( m_xDocsMgr.is() )
77 m_xDocsMgr->destroy();
80 //=========================================================================
82 // XInterface methods.
84 //=========================================================================
86 XINTERFACE_IMPL_4( ContentProvider,
87 lang::XTypeProvider,
88 lang::XServiceInfo,
89 ucb::XContentProvider,
90 frame::XTransientDocumentsDocumentContentFactory );
92 //=========================================================================
94 // XTypeProvider methods.
96 //=========================================================================
98 XTYPEPROVIDER_IMPL_4( ContentProvider,
99 lang::XTypeProvider,
100 lang::XServiceInfo,
101 ucb::XContentProvider,
102 frame::XTransientDocumentsDocumentContentFactory );
104 //=========================================================================
106 // XServiceInfo methods.
108 //=========================================================================
110 XSERVICEINFO_IMPL_1(
111 ContentProvider,
112 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
113 "com.sun.star.comp.ucb.TransientDocumentsContentProvider" ) ),
114 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
115 TDOC_CONTENT_PROVIDER_SERVICE_NAME ) ) );
117 //=========================================================================
119 // Service factory implementation.
121 //=========================================================================
123 ONE_INSTANCE_SERVICE_FACTORY_IMPL( ContentProvider );
125 //=========================================================================
127 // XContentProvider methods.
129 //=========================================================================
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 )
137 Uri aUri( Identifier->getContentIdentifier() );
138 if ( !aUri.isValid() )
139 throw ucb::IllegalIdentifierException(
140 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Invalid URL!" ) ),
141 Identifier );
143 // Normalize URI.
144 uno::Reference< ucb::XContentIdentifier > xCanonicId
145 = new ::ucbhelper::ContentIdentifier( m_xSMgr, 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_xSMgr, this, xCanonicId );
157 registerNewContent( xContent );
160 return xContent;
163 //=========================================================================
165 // XTransientDocumentsDocumentContentFactory methods.
167 //=========================================================================
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 )
175 // model -> id -> content identifier -> queryContent
176 if ( m_xDocsMgr.is() )
178 rtl::OUString aDocId = m_xDocsMgr->queryDocumentId( Model );
179 if ( aDocId.getLength() > 0 )
181 rtl::OUStringBuffer aBuffer;
182 aBuffer.appendAscii( TDOC_URL_SCHEME ":/" );
183 aBuffer.append( aDocId );
185 uno::Reference< ucb::XContentIdentifier > xId
186 = new ::ucbhelper::ContentIdentifier(
187 m_xSMgr, aBuffer.makeStringAndClear() );
189 osl::MutexGuard aGuard( m_aMutex );
191 // Check, if a content with given id already exists...
192 uno::Reference< ucb::XContent > xContent
193 = queryExistingContent( xId ).get();
195 if ( !xContent.is() )
197 // Create a new content.
198 xContent = Content::create( m_xSMgr, this, xId );
201 if ( xContent.is() )
202 return xContent;
204 // no content.
205 throw lang::IllegalArgumentException(
206 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
207 "Illegal Content Identifier!" ) ),
208 static_cast< cppu::OWeakObject * >( this ),
209 1 );
211 else
213 throw lang::IllegalArgumentException(
214 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
215 "Unable to obtain document id from model!" ) ),
216 static_cast< cppu::OWeakObject * >( this ),
217 1 );
220 else
222 throw lang::IllegalArgumentException(
223 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
224 "No Document Manager!" ) ),
225 static_cast< cppu::OWeakObject * >( this ),
226 1 );
230 //=========================================================================
232 // interface OfficeDocumentsEventListener
234 //=========================================================================
236 // virtual
237 void ContentProvider::notifyDocumentClosed( const rtl::OUString & rDocId )
239 osl::MutexGuard aGuard( getContentListMutex() );
241 ::ucbhelper::ContentRefList aAllContents;
242 queryExistingContents( aAllContents );
244 ::ucbhelper::ContentRefList::const_iterator it = aAllContents.begin();
245 ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
247 // Notify all content objects related to the closed doc.
249 bool bFoundDocumentContent = false;
250 rtl::Reference< Content > xRoot;
252 while ( it != end )
254 Uri aUri( (*it)->getIdentifier()->getContentIdentifier() );
255 OSL_ENSURE( aUri.isValid(),
256 "ContentProvider::notifyDocumentClosed - Invalid URI!" );
258 if ( !bFoundDocumentContent )
260 if ( aUri.isRoot() )
262 xRoot = static_cast< Content * >( (*it).get() );
264 else if ( aUri.isDocument() )
266 if ( aUri.getDocumentId() == rDocId )
268 bFoundDocumentContent = true;
270 // document content will notify removal of child itself;
271 // no need for the root to propagate this.
272 xRoot.clear();
277 if ( aUri.getDocumentId() == rDocId )
279 // Inform content.
280 rtl::Reference< Content > xContent
281 = static_cast< Content * >( (*it).get() );
283 xContent->notifyDocumentClosed();
286 ++it;
289 if ( xRoot.is() )
291 // No document content found for rDocId but root content
292 // instanciated. Root content must announce document removal
293 // to content event listeners.
294 xRoot->notifyChildRemoved( rDocId );
298 //=========================================================================
299 // virtual
300 void ContentProvider::notifyDocumentOpened( const rtl::OUString & rDocId )
302 osl::MutexGuard aGuard( getContentListMutex() );
304 ::ucbhelper::ContentRefList aAllContents;
305 queryExistingContents( aAllContents );
307 ::ucbhelper::ContentRefList::const_iterator it = aAllContents.begin();
308 ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
310 // Find root content. If instanciated let it propagate document insertion.
312 while ( it != end )
314 Uri aUri( (*it)->getIdentifier()->getContentIdentifier() );
315 OSL_ENSURE( aUri.isValid(),
316 "ContentProvider::notifyDocumentOpened - Invalid URI!" );
318 if ( aUri.isRoot() )
320 rtl::Reference< Content > xRoot
321 = static_cast< Content * >( (*it).get() );
322 xRoot->notifyChildInserted( rDocId );
324 // Done.
325 break;
328 ++it;
332 //=========================================================================
334 // Non-UNO
336 //=========================================================================
338 uno::Reference< embed::XStorage >
339 ContentProvider::queryStorage( const rtl::OUString & rUri,
340 StorageAccessMode eMode ) const
342 if ( m_xStgElemFac.is() )
346 return m_xStgElemFac->createStorage( rUri, eMode );
348 catch ( embed::InvalidStorageException const & )
350 OSL_ENSURE( false, "Caught InvalidStorageException!" );
352 catch ( lang::IllegalArgumentException const & )
354 OSL_ENSURE( false, "Caught IllegalArgumentException!" );
356 catch ( io::IOException const & )
358 // Okay to happen, for instance when the storage does not exist.
359 //OSL_ENSURE( false, "Caught IOException!" );
361 catch ( embed::StorageWrappedTargetException const & )
363 OSL_ENSURE( false, "Caught embed::StorageWrappedTargetException!" );
366 return uno::Reference< embed::XStorage >();
369 //=========================================================================
370 uno::Reference< embed::XStorage >
371 ContentProvider::queryStorageClone( const rtl::OUString & rUri ) const
373 if ( m_xStgElemFac.is() )
377 Uri aUri( rUri );
378 uno::Reference< embed::XStorage > xParentStorage
379 = m_xStgElemFac->createStorage( aUri.getParentUri(), READ );
380 uno::Reference< embed::XStorage > xStorage
381 = m_xStgElemFac->createTemporaryStorage();
383 xParentStorage->copyStorageElementLastCommitTo(
384 aUri.getDecodedName(), xStorage );
385 return xStorage;
387 catch ( embed::InvalidStorageException const & )
389 OSL_ENSURE( false, "Caught InvalidStorageException!" );
391 catch ( lang::IllegalArgumentException const & )
393 OSL_ENSURE( false, "Caught IllegalArgumentException!" );
395 catch ( io::IOException const & )
397 // Okay to happen, for instance when the storage does not exist.
398 //OSL_ENSURE( false, "Caught IOException!" );
400 catch ( embed::StorageWrappedTargetException const & )
402 OSL_ENSURE( false, "Caught embed::StorageWrappedTargetException!" );
406 return uno::Reference< embed::XStorage >();
409 //=========================================================================
410 uno::Reference< io::XInputStream >
411 ContentProvider::queryInputStream( const rtl::OUString & rUri,
412 const rtl::OUString & rPassword ) const
413 throw ( packages::WrongPasswordException )
415 if ( m_xStgElemFac.is() )
419 return m_xStgElemFac->createInputStream( rUri, rPassword );
421 catch ( embed::InvalidStorageException const & )
423 OSL_ENSURE( false, "Caught InvalidStorageException!" );
425 catch ( lang::IllegalArgumentException const & )
427 OSL_ENSURE( false, "Caught IllegalArgumentException!" );
429 catch ( io::IOException const & )
431 OSL_ENSURE( false, "Caught IOException!" );
433 catch ( embed::StorageWrappedTargetException const & )
435 OSL_ENSURE( false, "Caught embed::StorageWrappedTargetException!" );
437 // catch ( packages::WrongPasswordException const & )
438 // {
439 // // the key provided is wrong; rethrow; to be handled by caller.
440 // throw;
441 // }
443 return uno::Reference< io::XInputStream >();
446 //=========================================================================
447 uno::Reference< io::XOutputStream >
448 ContentProvider::queryOutputStream( const rtl::OUString & rUri,
449 const rtl::OUString & rPassword,
450 bool bTruncate ) const
451 throw ( packages::WrongPasswordException )
453 if ( m_xStgElemFac.is() )
457 return
458 m_xStgElemFac->createOutputStream( rUri, rPassword, bTruncate );
460 catch ( embed::InvalidStorageException const & )
462 OSL_ENSURE( false, "Caught InvalidStorageException!" );
464 catch ( lang::IllegalArgumentException const & )
466 OSL_ENSURE( false, "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_ENSURE( false, "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 >();
486 //=========================================================================
487 uno::Reference< io::XStream >
488 ContentProvider::queryStream( const rtl::OUString & rUri,
489 const rtl::OUString & rPassword,
490 bool bTruncate ) const
491 throw ( packages::WrongPasswordException )
493 if ( m_xStgElemFac.is() )
497 return m_xStgElemFac->createStream( rUri, rPassword, bTruncate );
499 catch ( embed::InvalidStorageException const & )
501 OSL_ENSURE( false, "Caught InvalidStorageException!" );
503 catch ( lang::IllegalArgumentException const & )
505 OSL_ENSURE( false, "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_ENSURE( false, "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 >();
525 //=========================================================================
526 bool ContentProvider::queryNamesOfChildren(
527 const rtl::OUString & rUri, uno::Sequence< rtl::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_ENSURE( false, "Caught InvalidStorageException!" );
567 catch ( lang::IllegalArgumentException const & )
569 OSL_ENSURE( false, "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_ENSURE( false,
579 "Caught embed::StorageWrappedTargetException!" );
583 return false;
586 //=========================================================================
587 rtl::OUString
588 ContentProvider::queryStorageTitle( const rtl::OUString & rUri ) const
590 rtl::OUString aTitle;
592 Uri aUri( rUri );
593 if ( aUri.isRoot() )
595 // always empty.
596 aTitle = rtl::OUString();
598 else if ( aUri.isDocument() )
600 // for documents, title shall not be derived from URL. It shall
601 // be somethimg more 'speaking' than just the document UID.
602 if ( m_xDocsMgr.is() )
603 aTitle = m_xDocsMgr->queryStorageTitle( aUri.getDocumentId() );
605 else
607 // derive title from URL
608 aTitle = aUri.getDecodedName();
611 OSL_ENSURE( ( aTitle.getLength() > 0 ) || aUri.isRoot(),
612 "ContentProvider::queryStorageTitle - empty title!" );
613 return aTitle;
616 //=========================================================================
617 uno::Reference< frame::XModel >
618 ContentProvider::queryDocumentModel( const rtl::OUString & rUri ) const
620 uno::Reference< frame::XModel > xModel;
622 if ( m_xDocsMgr.is() )
624 Uri aUri( rUri );
625 xModel = m_xDocsMgr->queryDocumentModel( aUri.getDocumentId() );
628 OSL_ENSURE( xModel.is(),
629 "ContentProvider::queryDocumentModel - no model!" );
630 return xModel;