summaryrefslogtreecommitdiff
path: root/framework/source/loadenv
diff options
context:
space:
mode:
authorKurt Zenker <kz@openoffice.org>2004-01-28 13:37:23 +0000
committerKurt Zenker <kz@openoffice.org>2004-01-28 13:37:23 +0000
commit77f6149ca46d59ab0f77bd0d18d007c9a8be1a32 (patch)
tree43018c4744b75dc6a1bd503c715034b4b2c96c17 /framework/source/loadenv
parent10e56bae4fc104d9c212652b7832a751dcd30d15 (diff)
INTEGRATION: CWS filtercfg (1.1.2); FILE ADDED
2003/12/01 11:16:42 as 1.1.2.16: #102620# handle assertions right 2003/11/27 09:54:14 as 1.1.2.15: #102620# dont handle UNKNOWN_CONTENT as illegal argument 2003/11/04 10:46:36 as 1.1.2.14: #102620# split sequenceadapter into different files/classes 2003/10/24 09:50:14 as 1.1.2.13: #102620# look for right complete query everytimes 2003/10/24 09:46:31 as 1.1.2.12: #102620# optimize classifyContent 2003/10/23 12:20:32 as 1.1.2.11: #102620# right handling for preselection, cancelled load requests, reactivation of controller 2003/10/17 04:39:00 as 1.1.2.10: #102620# fixes for type detection of types without filters but using frame loaders (db); solve refcount problem of loadenv class 2003/09/29 05:05:33 as 1.1.2.9: #102620# use right debug level for dump function 2003/09/26 06:46:32 as 1.1.2.8: #102620# add static helper for loadComponentFromURL() 2003/09/08 08:14:17 as 1.1.2.7: #102620# use new guard to handle action locks on tasks 2003/08/26 05:38:05 as 1.1.2.6: #102620# declare same exceptions as defined 2003/08/26 05:30:28 as 1.1.2.5: #102620# declare same exceptions as defined 2003/08/21 11:14:30 as 1.1.2.4: #102620# remove code for ArgumentAnalyzer, Plugin ...; restructure include dirs; establish new shared loader source 2003/08/14 12:01:18 as 1.1.2.3: #102620# remove obsolete componentloader 2003/08/13 06:06:00 as 1.1.2.2: #102620# new version, new functions 2003/08/04 08:26:16 as 1.1.2.1: #102620# new shared source for loading using dispatch & loadComponentFromURL
Diffstat (limited to 'framework/source/loadenv')
-rw-r--r--framework/source/loadenv/loadenv.cxx1490
1 files changed, 1490 insertions, 0 deletions
diff --git a/framework/source/loadenv/loadenv.cxx b/framework/source/loadenv/loadenv.cxx
new file mode 100644
index 000000000000..240df0fae555
--- /dev/null
+++ b/framework/source/loadenv/loadenv.cxx
@@ -0,0 +1,1490 @@
+/*************************************************************************
+ *
+ * $RCSfile: loadenv.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: kz $ $Date: 2004-01-28 14:37:23 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+//_______________________________________________
+// includes of own project
+
+#ifndef __FRAMEWORK_LOADENV_LOADENV_HXX_
+#include <loadenv/loadenv.hxx>
+#endif
+
+#ifndef __FRAMEWORK_LOADENV_TARGETHELPER_HXX_
+#include <loadenv/targethelper.hxx>
+#endif
+
+#ifndef __FRAMEWORK_CLASSES_FRAMELISTANALYZER_HXX_
+#include <classes/framelistanalyzer.hxx>
+#endif
+
+#ifndef __FRAMEWORK_CONSTANT_FILTER_HXX_
+#include <constant/filter.hxx>
+#endif
+
+#ifndef __FRAMEWORK_CONSTANT_FRAMELOADER_HXX_
+#include <constant/frameloader.hxx>
+#endif
+
+#ifndef __FRAMEWORK_CONSTANT_CONTENTHANDLER_HXX_
+#include <constant/contenthandler.hxx>
+#endif
+
+#ifndef __FRAMEWORK_CONSTANT_MEDIADESCRIPTOR_HXX_
+#include <constant/mediadescriptor.hxx>
+#endif
+
+#ifndef __FRAMEWORK_CONSTANT_CONTAINERQUERY_HXX_
+#include <constant/containerquery.hxx>
+#endif
+
+#ifndef __FRAMEWORK_INTERACTION_STILLINTERACTION_HXX_
+#include <interaction/stillinteraction.hxx>
+#endif
+
+#ifndef __FRAMEWORK_THREADHELP_WRITEGUARD_HXX_
+#include <threadhelp/writeguard.hxx>
+#endif
+
+#ifndef __FRAMEWORK_THREADHELP_READGUARD_HXX_
+#include <threadhelp/readguard.hxx>
+#endif
+
+#ifndef __FRAMEWORK_THREADHELP_RESETABLEGUARD_HXX_
+#include <threadhelp/resetableguard.hxx>
+#endif
+
+#ifndef __FRAMEWORK_PROTOCOLS_H_
+#include <protocols.h>
+#endif
+
+#ifndef __FRAMEWORK_SERVICES_H_
+#include <services.h>
+#endif
+
+//_______________________________________________
+// includes of uno interface
+
+#ifndef _COM_SUN_STAR_UNO_RUNTIMEEXCEPTION_HPP_
+#include <com/sun/star/uno/RuntimeException.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_FRAME_DISPATCHRESULTSTATE_HPP_
+#include <com/sun/star/frame/DispatchResultState.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_UTIL_XURLTRANSFORMER_HPP_
+#include <com/sun/star/util/XURLTransformer.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_UCB_XCONTENTPROVIDERMANAGER_HPP_
+#include <com/sun/star/ucb/XContentProviderManager.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_UTIL_XCLOSEABLE_HPP_
+#include <com/sun/star/util/XCloseable.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
+#include <com/sun/star/lang/XComponent.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_AWT_XWINDOW_HPP_
+#include <com/sun/star/awt/XWindow.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_AWT_XTOPWINDOW_HPP_
+#include <com/sun/star/awt/XTopWindow.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_
+#include <com/sun/star/frame/XModel.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_FRAME_XFRAMELOADER_HPP_
+#include <com/sun/star/frame/XFrameLoader.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_FRAME_XSYNCHRONOUSFRAMELOADER_HPP_
+#include <com/sun/star/frame/XSynchronousFrameLoader.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_FRAME_XNOTIFYINGDISPATCH_HPP_
+#include <com/sun/star/frame/XNotifyingDispatch.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_TASK_XSTATUSINDICATORFACTORY_HPP_
+#include <com/sun/star/task/XStatusIndicatorFactory.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_TASK_XSTATUSINDICATOR_HPP_
+#include <com/sun/star/task/XStatusIndicator.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_UTIL_XMODIFIABLE_HPP_
+#include <com/sun/star/util/XModifiable.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_FRAME_XDISPATCHPROVIDER_HPP_
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_DOCUMENT_XTYPEDETECTION_HPP_
+#include <com/sun/star/document/XTypeDetection.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_DOCUMENT_XACTIONLOCKABLE_HPP_
+#include <com/sun/star/document/XActionLockable.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HPP_
+#include <com/sun/star/io/XInputStream.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_TASK_XINTERACTIONHANDLER_HPP_
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
+#include <com/sun/star/container/XNameAccess.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_CONTAINER_XCONTAINERQUERY_HPP_
+#include <com/sun/star/container/XContainerQuery.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_CONTAINER_XENUMERATION_HPP_
+#include <com/sun/star/container/XEnumeration.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_DOCUMENT_MACROEXECMODE_HPP_
+#include <com/sun/star/document/MacroExecMode.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_DOCUMENT_UPDATEDOCMODE_HPP_
+#include <com/sun/star/document/UpdateDocMode.hpp>
+#endif
+
+//_______________________________________________
+// includes of an other project
+
+#ifndef INCLUDED_SVTOOLS_MODULEOPTIONS_HXX
+#include <svtools/moduleoptions.hxx>
+#endif
+
+#ifndef _UNOTOOLS_PROCESSFACTORY_HXX_
+#include <unotools/processfactory.hxx>
+#endif
+
+#ifndef _RTL_USTRBUF_HXX_
+#include <rtl/ustrbuf.hxx>
+#endif
+
+#ifndef _SV_SVAPP_HXX
+#include <vcl/svapp.hxx>
+#endif
+
+//_______________________________________________
+// namespace
+
+namespace framework{
+
+// may there exist already a define .-(
+#ifndef css
+namespace css = ::com::sun::star;
+#endif
+
+//_______________________________________________
+// declarations
+
+class LoadEnvListener : private ThreadHelpBase
+ , public ::cppu::WeakImplHelper2< css::frame::XLoadEventListener ,
+ css::frame::XDispatchResultListener >
+{
+ private:
+
+ void** m_ppCheck ;
+ LoadEnv* m_pLoadEnv;
+
+ public:
+
+ //_______________________________________
+ LoadEnvListener(void* pCheck ,
+ LoadEnv* pLoadEnv)
+ {
+ m_ppCheck = &pCheck ;
+ m_pLoadEnv = pLoadEnv;
+ }
+
+ //_______________________________________
+ // frame.XLoadEventListener
+ virtual void SAL_CALL loadFinished(const css::uno::Reference< css::frame::XFrameLoader >& xLoader)
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL loadCancelled(const css::uno::Reference< css::frame::XFrameLoader >& xLoader)
+ throw(css::uno::RuntimeException);
+
+ //_______________________________________
+ // frame.XDispatchResultListener
+ virtual void SAL_CALL dispatchFinished(const css::frame::DispatchResultEvent& aEvent)
+ throw(css::uno::RuntimeException);
+
+ //_______________________________________
+ // lang.XEventListener
+ virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent)
+ throw(css::uno::RuntimeException);
+};
+
+/*-----------------------------------------------
+ 14.10.2003 13:43
+-----------------------------------------------*/
+LoadEnv::LoadEnv(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+ throw(LoadEnvException, css::uno::RuntimeException)
+ : ThreadHelpBase( )
+ , m_xSMGR (xSMGR)
+ , m_pCheck (this )
+{
+}
+
+/*-----------------------------------------------
+ 14.10.2003 13:43
+-----------------------------------------------*/
+LoadEnv::~LoadEnv()
+{
+ m_pCheck = 0;
+}
+
+/*-----------------------------------------------
+ 10.09.2003 14:05
+-----------------------------------------------*/
+css::uno::Reference< css::lang::XComponent > LoadEnv::loadComponentFromURL(const css::uno::Reference< css::frame::XComponentLoader >& xLoader,
+ const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ const ::rtl::OUString& sURL ,
+ const ::rtl::OUString& sTarget,
+ sal_Int32 nFlags ,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArgs )
+ throw(css::lang::IllegalArgumentException,
+ css::io::IOException ,
+ css::uno::RuntimeException )
+{
+ TargetHelper::ESpecialTarget eTarget = TargetHelper::classifyTarget(sTarget);
+ if (
+ (eTarget != TargetHelper::E_NOT_SPECIAL) &&
+ (eTarget != TargetHelper::E_BLANK ) &&
+ (eTarget != TargetHelper::E_DEFAULT ) &&
+ (eTarget != TargetHelper::E_HELPTASK )
+ )
+ throw css::lang::IllegalArgumentException(
+ ::rtl::OUString::createFromAscii("The given target name is not supported at the desktop instance!"),
+ xLoader,
+ 2);
+
+ css::uno::Reference< css::lang::XComponent > xComponent;
+
+ try
+ {
+ LoadEnv aEnv(xSMGR);
+
+ aEnv.initializeLoading(sURL,
+ lArgs,
+ css::uno::Reference< css::frame::XFrame >(xLoader, css::uno::UNO_QUERY),
+ sTarget,
+ nFlags,
+ LoadEnv::E_NO_FEATURE);
+ aEnv.startLoading();
+ aEnv.waitWhileLoading(); // wait for ever!
+
+ xComponent = aEnv.getTargetComponent();
+ }
+ catch(const LoadEnvException& ex)
+ {
+ switch(ex.m_nID)
+ {
+ case LoadEnvException::ID_INVALID_MEDIADESCRIPTOR:
+ throw css::lang::IllegalArgumentException(
+ ::rtl::OUString::createFromAscii("Optional list of arguments seem to be corrupted."),
+ xLoader,
+ 4);
+ break;
+
+ default: xComponent.clear();
+ break;
+ }
+ }
+
+ return xComponent;
+}
+
+/*-----------------------------------------------
+ 20.08.2003 09:49
+-----------------------------------------------*/
+void LoadEnv::initializeLoading(const ::rtl::OUString& sURL ,
+ const css::uno::Sequence< css::beans::PropertyValue >& lMediaDescriptor,
+ const css::uno::Reference< css::frame::XFrame >& xBaseFrame ,
+ const ::rtl::OUString& sTarget ,
+ sal_Int32 nSearchFlags ,
+ EFeature eFeature , // => use default ...
+ EContentType eContentType ) // => use default ...
+ throw(LoadEnvException, css::uno::RuntimeException)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ // Handle still running processes!
+ if (m_xAsynchronousJob.is())
+ throw LoadEnvException(LoadEnvException::ID_STILL_RUNNING);
+
+ // take over all new parameters.
+ m_xTargetFrame.clear();
+ m_xBaseFrame = xBaseFrame ;
+ m_lMediaDescriptor << lMediaDescriptor ;
+ m_sTarget = sTarget ;
+ m_nSearchFlags = nSearchFlags ;
+ m_eFeature = eFeature ;
+ m_eContentType = eContentType ;
+ m_bCloseFrameOnError = sal_False ;
+ m_bReactivateControllerOnError = sal_False ;
+ m_bLoaded = sal_False ;
+
+ // try to find out, if its realy a content, which can be loaded or must be "handled"
+ // We use a default value for this in-parameter. Then we have to start a complex check method
+ // internaly. But if this check was already done outside it can be supressed to perform
+ // the load request. We take over the result then!
+ if (m_eContentType == E_UNSUPPORTED_CONTENT)
+ {
+ m_eContentType = LoadEnv::classifyContent(sURL, lMediaDescriptor);
+ if (m_eContentType == E_UNSUPPORTED_CONTENT)
+ throw LoadEnvException(LoadEnvException::ID_UNSUPPORTED_CONTENT);
+ }
+
+ // make URL part of the MediaDescriptor
+ // It doesnt mater, if its already an item of it.
+ // It must be the same value ... so we can overwrite it :-)
+ m_lMediaDescriptor[::framework::constant::MediaDescriptor::PROP_URL] <<= sURL;
+
+ // parse it - because some following code require that
+ m_aURL.Complete = sURL;
+ css::uno::Reference< css::util::XURLTransformer > xParser(m_xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY);
+ xParser->parseStrict(m_aURL);
+
+ // By the way: remove the old and deprecated value "FileName" from the descriptor!
+ ::comphelper::SequenceAsHashMap::iterator pIt = m_lMediaDescriptor.find(::framework::constant::MediaDescriptor::PROP_FILENAME);
+ if (pIt != m_lMediaDescriptor.end())
+ m_lMediaDescriptor.erase(pIt);
+
+ // patch the MediaDescriptor, so it fullfill the outside requirements
+ // Means especialy items like e.g. UI InteractionHandler, Status Indicator,
+ // MacroExecutionMode etcpp.
+
+ /*TODO progress is bound to a frame ... How can we set it here? */
+
+ css::uno::Reference< css::task::XInteractionHandler > xInteractionHandler;
+ sal_Int16 nMacroMode ;
+ sal_Int16 nUpdateMode ;
+
+ // UI mode
+ if (
+ ((m_eFeature & E_WORK_WITH_UI) == E_WORK_WITH_UI) &&
+ (m_lMediaDescriptor.getUnpackedValueOrDefault(::framework::constant::MediaDescriptor::PROP_HIDDEN , sal_False) == sal_True ) &&
+ (m_lMediaDescriptor.getUnpackedValueOrDefault(::framework::constant::MediaDescriptor::PROP_PREVIEW, sal_False) == sal_True )
+ )
+ {
+ nMacroMode = css::document::MacroExecMode::USE_CONFIG;
+ nUpdateMode = css::document::UpdateDocMode::ACCORDING_TO_CONFIG;
+ try
+ {
+ xInteractionHandler = css::uno::Reference< css::task::XInteractionHandler >(m_xSMGR->createInstance(IMPLEMENTATIONNAME_UIINTERACTIONHANDLER), css::uno::UNO_QUERY);
+ }
+ catch(const css::uno::RuntimeException&) {throw;}
+ catch(const css::uno::Exception& ) { }
+ }
+ // hidden mode
+ else
+ {
+ nMacroMode = css::document::MacroExecMode::NEVER_EXECUTE;
+ nUpdateMode = css::document::UpdateDocMode::NO_UPDATE;
+ StillInteraction* pInteraction = new StillInteraction();
+ xInteractionHandler = css::uno::Reference< css::task::XInteractionHandler >(static_cast< css::task::XInteractionHandler* >(pInteraction), css::uno::UNO_QUERY);
+ }
+
+ if (
+ (xInteractionHandler.is() ) &&
+ (m_lMediaDescriptor.find(::framework::constant::MediaDescriptor::PROP_INTERACTIONHANDLER) == m_lMediaDescriptor.end())
+ )
+ {
+ /*TODO um den InteractionHandler noch ein LogObject packen, welcher
+ die Art der Nutzung des Interaction Handlers protokolliert
+ und die Daten aufbereitet zur Verfgung stellt. Damit wre im Nachinein
+ eine Fehleranalyse mglich! */
+ m_lMediaDescriptor[::framework::constant::MediaDescriptor::PROP_INTERACTIONHANDLER] <<= xInteractionHandler;
+ }
+
+ if (m_lMediaDescriptor.find(::framework::constant::MediaDescriptor::PROP_MACROEXECUTIONMODE) == m_lMediaDescriptor.end())
+ m_lMediaDescriptor[::framework::constant::MediaDescriptor::PROP_MACROEXECUTIONMODE] <<= nMacroMode;
+
+ if (m_lMediaDescriptor.find(::framework::constant::MediaDescriptor::PROP_UPDATEDOCMODE) == m_lMediaDescriptor.end())
+ m_lMediaDescriptor[::framework::constant::MediaDescriptor::PROP_UPDATEDOCMODE] <<= nUpdateMode;
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+/*-----------------------------------------------
+ 15.08.2003 08:16
+-----------------------------------------------*/
+void LoadEnv::startLoading()
+ throw(LoadEnvException, css::uno::RuntimeException)
+{
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+
+ // Handle still running processes!
+ if (m_xAsynchronousJob.is())
+ throw LoadEnvException(LoadEnvException::ID_STILL_RUNNING);
+
+ // content can not be loaded or handled
+ // check "classifyContent()" failed before ...
+ if (m_eContentType == E_UNSUPPORTED_CONTENT)
+ throw LoadEnvException(LoadEnvException::ID_UNSUPPORTED_CONTENT);
+
+ // <- SAFE
+ aReadLock.unlock();
+
+ // detect its type/filter etcpp.
+ // These information will be available by the
+ // used descriptor member afterwards and is needed
+ // for all following operations!
+ // Note: An exception will be thrown, in case operation was not successfully ...
+ impl_detectTypeAndFilter();
+
+ // start loading the content ...
+ // Attention: Dont check m_eContentType deeper then UNSUPPORTED/SUPPORTED!
+ // Because it was made in th easiest way ... may a flat detection was made only.
+ // And such simple detection can fail some times .-)
+ // Use another strategy here. Try it and let it run into the case "loading not possible".
+ sal_Bool bStarted = sal_False;
+ if ((m_eFeature & E_ALLOW_CONTENTHANDLER) == E_ALLOW_CONTENTHANDLER)
+ bStarted = impl_handleContent();
+
+ if (!bStarted)
+ bStarted = impl_loadContent();
+
+ // not started => general error
+ // We cant say - what was the reason for.
+ if (!bStarted)
+ throw LoadEnvException(LoadEnvException::ID_GENERAL_ERROR);
+}
+
+/*-----------------------------------------------
+ 15.08.2003 09:50
+ TODO
+ First draft does not implement timeout using [ms].
+ Current implementation counts yield calls only ...
+-----------------------------------------------*/
+sal_Bool LoadEnv::waitWhileLoading(sal_uInt32 nTimeout)
+ throw(LoadEnvException, css::uno::RuntimeException)
+{
+ // Because its not a good idea to block the main thread
+ // (and we cant be shure that we are currently not used inside the
+ // main thread!), we cant use conditions here realy. We must yield
+ // in an intellegent manner :-)
+
+ sal_Int32 nTime = nTimeout;
+ while(true)
+ {
+ // SAFE -> ------------------------------
+ ReadGuard aReadLock1(m_aLock);
+ if (!m_xAsynchronousJob.is())
+ break;
+ aReadLock1.unlock();
+ // <- SAFE ------------------------------
+
+ Application::Yield();
+
+ // forever!
+ if (nTimeout==0)
+ continue;
+
+ // timed out?
+ --nTime;
+ if (nTime<1)
+ break;
+ }
+
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock2(m_aLock);
+ return !m_xAsynchronousJob.is();
+ // <- SAFE ----------------------------------
+}
+
+/*-----------------------------------------------
+ 20.08.2003 10:00
+-----------------------------------------------*/
+void LoadEnv::cancelLoading()
+ throw(LoadEnvException, css::uno::RuntimeException)
+{
+ // PARTIAL(!) SAFE -> ------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ // Still running? Might waitWhileLoading()
+ // runned into the timeout!
+ if (m_xAsynchronousJob.is())
+ {
+ // try to cancel it ... if its an asynchronous frame loader
+ css::uno::Reference< css::frame::XFrameLoader > xAsyncLoader(m_xAsynchronousJob, css::uno::UNO_QUERY);
+ if (xAsyncLoader.is())
+ {
+ aReadLock.unlock();
+ // <- BREAK SAFE ------------------------------
+ xAsyncLoader->cancel();
+ // <- RESTART SAFE ----------------------------
+ aReadLock.lock();
+ /* Attention:
+ After returning from any cancel/dispose call, neither the frame nor weself
+ may be called back. Because only we can cancel this job, we already know
+ the result! => Thats why its not usefull nor neccessary to wait for any
+ asynchronous listener notification.
+ */
+ m_bLoaded = sal_False;
+ m_xAsynchronousJob.clear();
+ }
+ // or may be its a content handler? Such handler cant be cancelled in its running
+ // operation :-( And we cant deregister us there again :-(
+ // => The only chance is an exception :-)
+ else
+ throw LoadEnvException(LoadEnvException::ID_STILL_RUNNING);
+ }
+
+ impl_reactForLoadingState();
+
+ aReadLock.unlock();
+ // <- PARTIAL(!) SAFE ------------------------------
+}
+
+/*-----------------------------------------------
+ 14.08.2003 13:33
+-----------------------------------------------*/
+css::uno::Reference< css::frame::XFrame > LoadEnv::getTarget() const
+{
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ return m_xTargetFrame;
+ // <- SAFE
+}
+
+/*-----------------------------------------------
+ 14.08.2003 13:35
+-----------------------------------------------*/
+css::uno::Reference< css::lang::XComponent > LoadEnv::getTargetComponent() const
+{
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+
+ if (!m_xTargetFrame.is())
+ return css::uno::Reference< css::lang::XComponent >();
+
+ css::uno::Reference< css::frame::XController > xController = m_xTargetFrame->getController();
+ if (!xController.is())
+ return css::uno::Reference< css::lang::XComponent >(m_xTargetFrame->getComponentWindow(), css::uno::UNO_QUERY);
+
+ css::uno::Reference< css::frame::XModel > xModel = xController->getModel();
+ if (!xModel.is())
+ return css::uno::Reference< css::lang::XComponent >(xController, css::uno::UNO_QUERY);
+
+ return css::uno::Reference< css::lang::XComponent >(xModel, css::uno::UNO_QUERY);
+ // <- SAFE
+}
+
+/*-----------------------------------------------
+ 15.08.2003 11:15
+-----------------------------------------------*/
+void SAL_CALL LoadEnvListener::loadFinished(const css::uno::Reference< css::frame::XFrameLoader >& xLoader)
+ throw(css::uno::RuntimeException)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ if (m_ppCheck && *m_ppCheck)
+ m_pLoadEnv->impl_setResult(sal_True);
+ m_ppCheck = NULL;
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+/*-----------------------------------------------
+ 14.10.2003 12:23
+-----------------------------------------------*/
+void SAL_CALL LoadEnvListener::loadCancelled(const css::uno::Reference< css::frame::XFrameLoader >& xLoader)
+ throw(css::uno::RuntimeException)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ if (m_ppCheck && *m_ppCheck)
+ m_pLoadEnv->impl_setResult(sal_False);
+ m_ppCheck = NULL;
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+/*-----------------------------------------------
+ 14.10.2003 12:23
+-----------------------------------------------*/
+void SAL_CALL LoadEnvListener::dispatchFinished(const css::frame::DispatchResultEvent& aEvent)
+ throw(css::uno::RuntimeException)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ if (!m_ppCheck || !*m_ppCheck)
+ return;
+
+ switch(aEvent.State)
+ {
+ case css::frame::DispatchResultState::FAILURE :
+ m_pLoadEnv->impl_setResult(sal_False);
+ break;
+
+ case css::frame::DispatchResultState::SUCCESS :
+ m_pLoadEnv->impl_setResult(sal_False);
+ break;
+
+ case css::frame::DispatchResultState::DONTKNOW :
+ m_pLoadEnv->impl_setResult(sal_False);
+ break;
+ }
+ m_ppCheck = NULL;
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+/*-----------------------------------------------
+ 14.10.2003 12:24
+-----------------------------------------------*/
+void SAL_CALL LoadEnvListener::disposing(const css::lang::EventObject& aEvent)
+ throw(css::uno::RuntimeException)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ if (m_ppCheck && *m_ppCheck)
+ m_pLoadEnv->impl_setResult(sal_False);
+ m_ppCheck = NULL;
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+/*-----------------------------------------------
+ 14.10.2003 12:20
+-----------------------------------------------*/
+void LoadEnv::impl_setResult(sal_Bool bResult)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ m_bLoaded = bResult;
+
+ impl_reactForLoadingState();
+
+ // clearing of this reference will unblock waitWhileLoading()!
+ // So we must be shure, that loading process was realy finished.
+ // => do it as last operation of this method ...
+ m_xAsynchronousJob.clear();
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+/*-----------------------------------------------
+ 23.07.2003 13:22
+ TODO: Is it a good idea to change Sequence<>
+ parameter to stl-adapter?
+-----------------------------------------------*/
+LoadEnv::EContentType LoadEnv::classifyContent(const ::rtl::OUString& sURL ,
+ const css::uno::Sequence< css::beans::PropertyValue >& lMediaDescriptor)
+{
+ //-------------------------------------------
+ // (i) Filter some special well known URL protocols,
+ // which can not be handled or loaded in general.
+ // Of course an empty URL must be ignored here too.
+ // Note: These URL schemata are fix and well known ...
+ // But there can be some additional ones, which was not
+ // defined at implementation time of this class :-(
+ // So we have to make shure, that the following code
+ // can detect such protocol schemata too :-)
+
+ if(
+ (!sURL.getLength() ) ||
+ (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_UNO )) ||
+ (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_SLOT )) ||
+ (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_MACRO )) ||
+ (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_SERVICE)) ||
+ (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_MAILTO )) ||
+ (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_NEWS ))
+ )
+ {
+ return E_UNSUPPORTED_CONTENT;
+ }
+
+ //-------------------------------------------
+ // (ii) Some special URLs indicates a given input stream,
+ // a full featured document model directly or
+ // specify a request for opening an empty document.
+ // Such contents are loadable in general.
+ // But we have to check, if the media descriptor contains
+ // all needed resources. If they are missing - the following
+ // load request will fail.
+
+ /* Attention: The following code cant work on such special URLs!
+ It should not break the office .. but it make no sense
+ to start expensive object creations and complex search
+ algorithm if its clear, that such URLs must be handled
+ in a special way .-)
+ */
+
+ // creation of new documents
+ if (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_PRIVATE_FACTORY))
+ return E_CAN_BE_LOADED;
+
+ // using of an existing input stream
+ ::comphelper::SequenceAsHashMap stlMediaDescriptor(lMediaDescriptor);
+ ::comphelper::SequenceAsHashMap::const_iterator pIt;
+ if (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_PRIVATE_STREAM))
+ {
+ pIt = stlMediaDescriptor.find(::framework::constant::MediaDescriptor::PROP_INPUTSTREAM);
+ css::uno::Reference< css::io::XInputStream > xStream;
+ if (pIt == stlMediaDescriptor.end())
+ pIt->second >>= xStream;
+ if (xStream.is())
+ return E_CAN_BE_LOADED;
+ LOG_WARNING("LoadEnv::classifyContent()", "loading from stream with right URL but invalid stream detected")
+ return E_UNSUPPORTED_CONTENT;
+ }
+
+ // using of a full featured document
+ if (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_PRIVATE_OBJECT))
+ {
+ pIt = stlMediaDescriptor.find(::framework::constant::MediaDescriptor::PROP_MODEL);
+ css::uno::Reference< css::frame::XModel > xModel;
+ if (pIt == stlMediaDescriptor.end())
+ pIt->second >>= xModel;
+ if (xModel.is())
+ return E_CAN_BE_LOADED;
+ LOG_WARNING("LoadEnv::classifyContent()", "loading with object with right URL but invalid object detected")
+ return E_UNSUPPORTED_CONTENT;
+ }
+
+ // following operatons can work on an internal type name only :-(
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::utl::getProcessServiceFactory();
+ css::uno::Reference< css::document::XTypeDetection > xDetect(xSMGR->createInstance(SERVICENAME_TYPEDETECTION), css::uno::UNO_QUERY);
+
+ ::rtl::OUString sType = xDetect->queryTypeByURL(sURL);
+
+ css::uno::Sequence< css::beans::NamedValue > lQuery(1) ;
+ css::uno::Reference< css::container::XContainerQuery > xContainer ;
+ css::uno::Reference< css::container::XEnumeration > xSet ;
+ css::uno::Sequence< ::rtl::OUString > lTypesReg(1);
+
+ /*
+ //-------------------------------------------
+ lQuery[0].Name = ::framework::constant::Filter::PROP_TYPE;
+ lQuery[0].Value <<= sType;
+
+ xContainer = css::uno::Reference< css::container::XContainerQuery >(xSMGR->createInstance(SERVICENAME_FILTERFACTORY), css::uno::UNO_QUERY);
+ xSet = xContainer->createSubSetEnumerationByProperties(lQuery);
+ // at least one registered frame loader is enough!
+ if (xSet->hasMoreElements())
+ return E_CAN_BE_LOADED;
+ */
+
+ //-------------------------------------------
+ // (iii) If a FrameLoader service (or at least
+ // a Filter) can be found, which supports
+ // this URL - it must be a loadable content.
+ // Because both items are registered for types
+ // its enough to check for frame loaders only.
+ // Mos of our filters are handled by our global
+ // default loader. But there exist some specialized
+ // loader, which does not work on top of filters!
+ // So its not enough to search on the filter configuration.
+ // Further its not enough to search for types!
+ // Because there exist some types, which are referenced by
+ // other objects ... but not by filters nor frame loaders!
+
+ lTypesReg[0] = sType;
+ lQuery[0].Name = ::framework::constant::FrameLoader::PROP_TYPES;
+ lQuery[0].Value <<= lTypesReg;
+
+ xContainer = css::uno::Reference< css::container::XContainerQuery >(xSMGR->createInstance(SERVICENAME_FRAMELOADERFACTORY), css::uno::UNO_QUERY);
+ xSet = xContainer->createSubSetEnumerationByProperties(lQuery);
+ // at least one registered frame loader is enough!
+ if (xSet->hasMoreElements())
+ return E_CAN_BE_LOADED;
+
+ //-------------------------------------------
+ // (iv) Some URL protocols are supported by special services.
+ // E.g. ContentHandler.
+ // Such contents can be handled ... but not loaded.
+
+ lTypesReg[0] = sType;
+ lQuery[0].Name = ::framework::constant::ContentHandler::PROP_TYPES;
+ lQuery[0].Value <<= lTypesReg;
+
+ xContainer = css::uno::Reference< css::container::XContainerQuery >(xSMGR->createInstance(SERVICENAME_CONTENTHANDLERFACTORY), css::uno::UNO_QUERY);
+ xSet = xContainer->createSubSetEnumerationByProperties(lQuery);
+ // at least one registered content handler is enough!
+ if (xSet->hasMoreElements())
+ return E_CAN_BE_HANDLED;
+
+ //-------------------------------------------
+ // (v) Last but not least the UCB is used inside office to
+ // load contents. He has a special configuration to know
+ // which URL schemata can be used inside office.
+ css::uno::Reference< css::ucb::XContentProviderManager > xUCB(xSMGR->createInstance(SERVICENAME_UCBCONTENTBROKER), css::uno::UNO_QUERY);
+ if (xUCB->queryContentProvider(sURL).is())
+ return E_CAN_BE_LOADED;
+
+ //-------------------------------------------
+ // (TODO) At this point, we have no idea .-)
+ // But it seems to be better, to break all
+ // further requests for this URL. Otherwhise
+ // we can run into some trouble.
+ LOG_WARNING("LoadEnv::classifyContent()", "realy an unsupported content?")
+ return E_UNSUPPORTED_CONTENT;
+}
+
+/*-----------------------------------------------
+ 03.11.2003 09:31
+-----------------------------------------------*/
+void LoadEnv::impl_detectTypeAndFilter()
+ throw(LoadEnvException, css::uno::RuntimeException)
+{
+ // SAFE ->
+ WriteGuard aWriteLock(m_aLock);
+
+ // start combined flat/deep detection
+ // It can agree with the current preselection or return any
+ // other type, which match to the specified content!
+
+ // Attention: Because our stl media descriptor is a copy of an uno sequence
+ // we cant use as an in/out parameter here. Copy it before and dont forget to
+ // actualize structure afterwards again!
+ css::uno::Reference< css::document::XTypeDetection > xDetect(m_xSMGR->createInstance(SERVICENAME_TYPEDETECTION), css::uno::UNO_QUERY);
+
+ css::uno::Sequence< css::beans::PropertyValue > lDescriptor;
+ m_lMediaDescriptor >> lDescriptor;
+ ::rtl::OUString sDetectedType = xDetect->queryTypeByDescriptor(lDescriptor, sal_True); /*TODO should deep detection be able for enable/disable it from outside? */
+ m_lMediaDescriptor << lDescriptor;
+
+ // a) content couldn't be detected successfully => return immediatly
+ // MediaDescriptor should be already up-to-date here!
+ if (!sDetectedType.getLength())
+ throw LoadEnvException(LoadEnvException::ID_UNSUPPORTED_CONTENT);
+
+ // b) if detection was successfully => update the descriptor
+ m_lMediaDescriptor[::framework::constant::MediaDescriptor::PROP_TYPENAME] <<= sDetectedType;
+
+ aWriteLock.unlock();
+ // <- SAFE
+}
+
+/*-----------------------------------------------
+ 15.08.2003 09:38
+-----------------------------------------------*/
+sal_Bool LoadEnv::impl_handleContent()
+ throw(LoadEnvException, css::uno::RuntimeException)
+{
+ // SAFE -> -----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ // the type must exist inside the descriptor ... otherwhise this class is implemented wrong :-)
+ ::rtl::OUString sType = m_lMediaDescriptor.getUnpackedValueOrDefault(::framework::constant::MediaDescriptor::PROP_TYPENAME, ::rtl::OUString());
+ if (!sType.getLength())
+ throw LoadEnvException(LoadEnvException::ID_INVALID_MEDIADESCRIPTOR);
+
+ // convert media descriptor and URL to right format for later interface call!
+ css::uno::Sequence< css::beans::PropertyValue > lDescriptor;
+ m_lMediaDescriptor >> lDescriptor;
+ css::util::URL aURL = m_aURL;
+
+ // get neccessary container to query for a handler object
+ css::uno::Reference< css::lang::XMultiServiceFactory > xFactory(m_xSMGR->createInstance(SERVICENAME_CONTENTHANDLERFACTORY), css::uno::UNO_QUERY);
+ css::uno::Reference< css::container::XContainerQuery > xQuery (xFactory , css::uno::UNO_QUERY);
+
+ aReadLock.unlock();
+ // <- SAFE -----------------------------------
+
+ // query
+ css::uno::Sequence< ::rtl::OUString > lTypeReg(1);
+ lTypeReg[0] = sType;
+
+ css::uno::Sequence< css::beans::NamedValue > lQuery(1);
+ lQuery[0].Name = ::framework::constant::ContentHandler::PROP_TYPES;
+ lQuery[0].Value <<= lTypeReg;
+
+ css::uno::Reference< css::container::XEnumeration > xSet = xQuery->createSubSetEnumerationByProperties(lQuery);
+ while(xSet->hasMoreElements())
+ {
+ ::comphelper::SequenceAsHashMap lProps (xSet->nextElement());
+ ::rtl::OUString sHandler = lProps.getUnpackedValueOrDefault(::framework::constant::ContentHandler::PROP_NAME, ::rtl::OUString());
+
+ css::uno::Reference< css::frame::XNotifyingDispatch > xHandler;
+ try
+ {
+ xHandler = css::uno::Reference< css::frame::XNotifyingDispatch >(xFactory->createInstance(sHandler), css::uno::UNO_QUERY);
+ if (!xHandler.is())
+ continue;
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception&)
+ { continue; }
+
+ // SAFE -> -----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+ m_xAsynchronousJob = xHandler;
+ m_pCheck = this;
+ LoadEnvListener* pListener = new LoadEnvListener(m_pCheck, this);
+ aWriteLock.unlock();
+ // <- SAFE -----------------------------------
+
+ css::uno::Reference< css::frame::XDispatchResultListener > xListener(static_cast< css::frame::XDispatchResultListener* >(pListener), css::uno::UNO_QUERY);
+ xHandler->dispatchWithNotification(aURL, lDescriptor, xListener);
+
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+/*-----------------------------------------------
+ 15.08.2003 09:35
+-----------------------------------------------*/
+sal_Bool LoadEnv::impl_loadContent()
+ throw(LoadEnvException, css::uno::RuntimeException)
+{
+ // SAFE -> -----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ // search or create right target frame
+ if (TargetHelper::matchSpecialTarget(m_sTarget, TargetHelper::E_DEFAULT))
+ {
+ m_xTargetFrame = impl_searchAlreadyLoaded();
+ if (!m_xTargetFrame.is())
+ m_xTargetFrame = impl_searchRecycleTarget();
+ if (!m_xTargetFrame.is())
+ {
+ m_xTargetFrame = m_xBaseFrame->findFrame(SPECIALTARGET_BLANK, 0);
+ // it is a new created target frame ... we have to close it
+ // in case loading failed. Because its an hidden frame now!
+ m_bCloseFrameOnError = m_xTargetFrame.is();
+ }
+ }
+ else
+ m_xTargetFrame = m_xBaseFrame->findFrame(m_sTarget, m_nSearchFlags);
+
+ if (!m_xTargetFrame.is())
+ throw LoadEnvException(LoadEnvException::ID_NO_TARGET_FOUND);
+ css::uno::Reference< css::frame::XFrame > xTargetFrame = m_xTargetFrame;
+
+ // OK - there is a valid target frame.
+ // But may be it contains already a valid document.
+ css::uno::Reference< css::frame::XController > xOldDoc = xTargetFrame->getController();
+ if (xOldDoc.is())
+ {
+ m_bReactivateControllerOnError = xOldDoc->suspend(sal_True);
+ if (!m_bReactivateControllerOnError)
+ throw LoadEnvException(LoadEnvException::ID_COULD_NOT_SUSPEND_CONTROLLER);
+ }
+
+ // Don't forget to lock task for following load process. Otherwise it could die
+ // during this operation runs by terminating the office or closing this task via api.
+ // If we set this lock "close()" will return false and closing will be broken.
+ // Attention: Don't forget to reset this lock again after finishing operation.
+ // Otherwise task AND office couldn't die!!!
+ // This includes gracefully handling of Exceptions (Runtime!) too ...
+ // Thats why we use a specialized guard, which will reset the lock
+ // if it will be run out of scope.
+
+ // Note further: ignore if this internal guard already contains a resource.
+ // Might impl_searchRecylcTarget() set it before. But incase this impl-method wasnt used
+ // and the target frame was new created ... this lock here must be set!
+ css::uno::Reference< css::document::XActionLockable > xTargetLock(xTargetFrame, css::uno::UNO_QUERY);
+ m_aTargetLock.setResource(xTargetLock);
+
+ // We need this type information to locate an registered frame loader
+ // Without such information we cant work!
+ ::rtl::OUString sType = m_lMediaDescriptor.getUnpackedValueOrDefault(::framework::constant::MediaDescriptor::PROP_TYPENAME, ::rtl::OUString());
+ if (!sType.getLength())
+ throw LoadEnvException(LoadEnvException::ID_INVALID_MEDIADESCRIPTOR);
+
+ // Add status indicator to descriptor. Loader can show an progresses then.
+ // But don't do it, if loading should be hidden or preview is used ...!
+ // So we prevent our code against wrong using. Why?
+ // It could be, that using of this progress could make trouble. e.g. He make window visible ...
+ // but shouldn't do that. But if no indicator is available ... nobody has a chance to do that!
+ sal_Bool bHidden = m_lMediaDescriptor.getUnpackedValueOrDefault(::framework::constant::MediaDescriptor::PROP_HIDDEN , sal_False );
+ sal_Bool bPreview = m_lMediaDescriptor.getUnpackedValueOrDefault(::framework::constant::MediaDescriptor::PROP_PREVIEW , sal_False );
+ css::uno::Reference< css::task::XStatusIndicator > xProgress = m_lMediaDescriptor.getUnpackedValueOrDefault(::framework::constant::MediaDescriptor::PROP_STATUSINDICATOR, css::uno::Reference< css::task::XStatusIndicator >());
+
+ if (!bHidden && !bPreview && !xProgress.is())
+ {
+ // Note: its an optional interface!
+ css::uno::Reference< css::task::XStatusIndicatorFactory > xProgressFactory(xTargetFrame, css::uno::UNO_QUERY);
+ if (xProgressFactory.is())
+ {
+ xProgress = xProgressFactory->createStatusIndicator();
+ if (xProgress.is())
+ m_lMediaDescriptor[::framework::constant::MediaDescriptor::PROP_STATUSINDICATOR] <<= xProgress;
+ }
+ }
+
+ // convert media descriptor and URL to right format for later interface call!
+ css::uno::Sequence< css::beans::PropertyValue > lDescriptor;
+ m_lMediaDescriptor >> lDescriptor;
+ ::rtl::OUString sURL = m_aURL.Complete;
+
+ // try to locate any interested frame loader
+ css::uno::Reference< css::lang::XMultiServiceFactory > xLoaderFactory(m_xSMGR->createInstance(SERVICENAME_FRAMELOADERFACTORY), css::uno::UNO_QUERY);
+ css::uno::Reference< css::container::XContainerQuery > xQuery (xLoaderFactory , css::uno::UNO_QUERY);
+
+ aWriteLock.unlock();
+ // <- SAFE -----------------------------------
+
+ css::uno::Sequence< ::rtl::OUString > lTypesReg(1);
+ lTypesReg[0] = sType;
+
+ css::uno::Sequence< css::beans::NamedValue > lQuery(1);
+ lQuery[0].Name = ::framework::constant::FrameLoader::PROP_TYPES;
+ lQuery[0].Value <<= lTypesReg;
+
+ css::uno::Reference< css::container::XEnumeration > xSet = xQuery->createSubSetEnumerationByProperties(lQuery);
+ while(xSet->hasMoreElements())
+ {
+ // try everyone ...
+ // Ignore any loader, which makes trouble :-)
+ ::comphelper::SequenceAsHashMap lLoaderProps(xSet->nextElement());
+ ::rtl::OUString sLoader = lLoaderProps.getUnpackedValueOrDefault(::framework::constant::FrameLoader::PROP_NAME, ::rtl::OUString());
+ css::uno::Reference< css::uno::XInterface > xLoader ;
+ try
+ {
+ xLoader = xLoaderFactory->createInstance(sLoader);
+ if (!xLoader.is())
+ continue;
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception&)
+ { continue; }
+
+ css::uno::Reference< css::frame::XFrameLoader > xAsyncLoader(xLoader, css::uno::UNO_QUERY);
+ css::uno::Reference< css::frame::XSynchronousFrameLoader > xSyncLoader (xLoader, css::uno::UNO_QUERY);
+
+ if (xAsyncLoader.is())
+ {
+ // SAFE -> -----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+ m_xAsynchronousJob = xAsyncLoader;
+ m_pCheck = this;
+ LoadEnvListener* pListener = new LoadEnvListener(m_pCheck, this);
+ aWriteLock.unlock();
+ // <- SAFE -----------------------------------
+
+ css::uno::Reference< css::frame::XLoadEventListener > xListener(static_cast< css::frame::XLoadEventListener* >(pListener), css::uno::UNO_QUERY);
+ xAsyncLoader->load(xTargetFrame, sURL, lDescriptor, xListener);
+
+ return sal_True;
+ }
+ else
+ if (xSyncLoader.is())
+ {
+ sal_Bool bResult = xSyncLoader->load(lDescriptor, xTargetFrame);
+ // react for the result here, so the outside waiting
+ // code can ask for it later.
+ impl_setResult(bResult);
+ // But the return value indicates a valid started(!) operation.
+ // And thats true everxtimes, we reach this line :-)
+ return sal_True;
+ }
+ }
+
+ aWriteLock.unlock();
+ // <- SAFE
+
+ return sal_False;
+}
+
+/*-----------------------------------------------
+ 31.07.2003 09:02
+-----------------------------------------------*/
+css::uno::Reference< css::frame::XFrame > LoadEnv::impl_searchAlreadyLoaded()
+ throw(LoadEnvException, css::uno::RuntimeException)
+{
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+
+ // such search is allowed for special requests only ...
+ // or better its not allowed for some requests in general :-)
+ if (
+ (!TargetHelper::matchSpecialTarget(m_sTarget, TargetHelper::E_DEFAULT) ) ||
+ (m_lMediaDescriptor.getUnpackedValueOrDefault(::framework::constant::MediaDescriptor::PROP_ASTEMPLATE , sal_False) == sal_True) ||
+ (m_lMediaDescriptor.getUnpackedValueOrDefault(::framework::constant::MediaDescriptor::PROP_HIDDEN , sal_False) == sal_True) ||
+ (m_lMediaDescriptor.getUnpackedValueOrDefault(::framework::constant::MediaDescriptor::PROP_OPENNEWVIEW, sal_False) == sal_True)
+ )
+ {
+ return css::uno::Reference< css::frame::XFrame >();
+ }
+
+ // check URL
+ // May its not usefull to start expensive document search, if it
+ // can fail only .. because we load from a stream or model directly!
+ if (
+ (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_STREAM )) ||
+ (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_OBJECT ))
+ /*TODO should be private:factory here tested too? */
+ )
+ {
+ return css::uno::Reference< css::frame::XFrame >();
+ }
+
+ // otherwhise - iterate through the tasks of the desktop container
+ // to find out, which of them might contains the requested document
+ css::uno::Reference< css::frame::XFramesSupplier > xSupplier(m_xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY);
+ css::uno::Reference< css::container::XIndexAccess > xTaskList(xSupplier->getFrames() , css::uno::UNO_QUERY);
+
+ if (!xTaskList.is())
+ return css::uno::Reference< css::frame::XFrame >(); // task list can be empty!
+
+ // Note: To detect if a document was alrady loaded before
+ // we check URLs here only. But might the existing and the requred
+ // document has different versions! Then its URLs are the same ...
+ sal_Int16 nNewVersion = m_lMediaDescriptor.getUnpackedValueOrDefault(::framework::constant::MediaDescriptor::PROP_VERSION, (sal_Int16)(-1));
+
+ sal_Int32 count = xTaskList->getCount();
+ for (sal_Int32 i=0; i<count; ++i)
+ {
+ try
+ {
+ // locate model of task
+ // Note: Without a model there is no chance to decide if
+ // this task contains the searched document or not!
+ css::uno::Reference< css::frame::XFrame > xTask;
+ xTaskList->getByIndex(i) >>= xTask;
+ if (!xTask.is())
+ continue;
+
+ css::uno::Reference< css::frame::XController > xController = xTask->getController();
+ if (!xController.is())
+ continue;
+
+ css::uno::Reference< css::frame::XModel > xModel = xController->getModel();
+ if (!xModel.is())
+ continue;
+
+ // don't check the complete URL here.
+ // use its main part - ignore optional jumpmarks!
+ if (!m_aURL.Main.equals(xModel->getURL()))
+ continue;
+
+ // get the original load arguments from the current document
+ // and decide if its realy the same then the one will be.
+ // It must be visible and must use the same file revision ...
+ // or must not have any file revision set (-1 == -1!)
+ ::comphelper::SequenceAsHashMap lOldDocDescriptor(xModel->getArgs());
+
+ if (lOldDocDescriptor.getUnpackedValueOrDefault(::framework::constant::MediaDescriptor::PROP_VERSION, (sal_Int32)(-1)) != nNewVersion)
+ continue;
+
+ if (lOldDocDescriptor.getUnpackedValueOrDefault(::framework::constant::MediaDescriptor::PROP_HIDDEN, sal_False) == sal_True)
+ continue;
+
+ // Now we are shure, that this task includes the searched document.
+ // It's time to activate it. As special feature we try to jump internaly
+ // if an optional jumpmark is given too.
+ if (m_aURL.Mark.getLength())
+ {
+ css::uno::Reference< css::frame::XDispatchProvider > xProvider(xTask, css::uno::UNO_QUERY);
+ if (xProvider.is())
+ {
+ css::uno::Reference< css::frame::XDispatch > xDispatcher = xProvider->queryDispatch(m_aURL, SPECIALTARGET_SELF, 0);
+ if (xDispatcher.is())
+ xDispatcher->dispatch(m_aURL, m_lMediaDescriptor.getAsConstPropertyValueList());
+ }
+ }
+
+ // bring it to front ...
+ css::uno::Reference< css::awt::XWindow > xTaskWindow = xTask->getContainerWindow();
+ css::uno::Reference< css::awt::XTopWindow > xTopWindow (xTaskWindow, css::uno::UNO_QUERY);
+ // Check it! May we are plugged into a browser/java canvas etcpp ...
+ // Then such "bring to front" operation isnt supported yet nor neccessary .-)
+ if (xTopWindow.is())
+ {
+ xTaskWindow->setVisible(sal_True);
+ xTopWindow->toFront();
+ }
+
+ // It doesn't matter if we was able to bring it to front.
+ // But we have found such task and can return it as our result.
+ return xTask;
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception&)
+ { continue; }
+ }
+
+ aReadLock.unlock();
+ // <- SAFE
+
+ return css::uno::Reference< css::frame::XFrame >();
+}
+
+/*-----------------------------------------------
+ 01.08.2003 13:19
+-----------------------------------------------*/
+css::uno::Reference< css::frame::XFrame > LoadEnv::impl_searchRecycleTarget()
+ throw(LoadEnvException, css::uno::RuntimeException)
+{
+ // SAFE -> ..................................
+ ReadGuard aReadLock(m_aLock);
+
+ // such search is allowed for special requests only ...
+ // or better its not allowed for some requests in general :-)
+ if (
+ (!TargetHelper::matchSpecialTarget(m_sTarget, TargetHelper::E_DEFAULT) ) ||
+ (m_lMediaDescriptor.getUnpackedValueOrDefault(::framework::constant::MediaDescriptor::PROP_ASTEMPLATE , sal_False) == sal_True) ||
+ (m_lMediaDescriptor.getUnpackedValueOrDefault(::framework::constant::MediaDescriptor::PROP_HIDDEN , sal_False) == sal_True) ||
+ (m_lMediaDescriptor.getUnpackedValueOrDefault(::framework::constant::MediaDescriptor::PROP_OPENNEWVIEW, sal_False) == sal_True)
+ )
+ {
+ return css::uno::Reference< css::frame::XFrame >();
+ }
+
+ if (
+ (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_STREAM )) ||
+ (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_OBJECT ))
+ /*TODO should be private:factory here tested too? */
+ )
+ {
+ return css::uno::Reference< css::frame::XFrame >();
+ }
+
+ // get access to the list of possible open tasks
+ css::uno::Reference< css::frame::XFramesSupplier > xSupplier(m_xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY);
+
+ // Attention! The special backing mode frame will be recycled everytimes!
+ FrameListAnalyzer aTasksAnalyzer(xSupplier, css::uno::Reference< css::frame::XFrame >(), FrameListAnalyzer::E_BACKINGCOMPONENT);
+ if (aTasksAnalyzer.m_xBackingComponent.is())
+ return aTasksAnalyzer.m_xBackingComponent;
+
+ // otherwhise - try to get the current active frame of the desktop
+ // container. Only this frame can be used here.
+ css::uno::Reference< css::frame::XFrame > xTask = xSupplier->getActiveFrame();
+
+ // not a real error - but might a focus problem!
+ if (!xTask.is())
+ return css::uno::Reference< css::frame::XFrame >();
+
+ // not a real error - may its a view only
+ css::uno::Reference< css::frame::XController > xController = xTask->getController();
+ if (!xController.is())
+ return css::uno::Reference< css::frame::XFrame >();
+
+ // not a real error - may its a db component instead of a full feartured office document
+ css::uno::Reference< css::frame::XModel > xModel = xController->getModel();
+ if (!xModel.is())
+ return css::uno::Reference< css::frame::XFrame >();
+
+ // get some more informations ...
+
+ // A valid set URL means: there is already a location for this document.
+ // => it was saved there or opened from there. Such Documents can not be used here.
+ // We search for empty document ... created by a private:factory/ URL!
+ if (xModel->getURL().getLength()>0)
+ return css::uno::Reference< css::frame::XFrame >();
+
+ // The old document must be unmodified ...
+ css::uno::Reference< css::util::XModifiable > xModified(xModel, css::uno::UNO_QUERY);
+ if (xModified->isModified())
+ return css::uno::Reference< css::frame::XFrame >();
+
+ // find out the application type of this document
+ // We can recycle only documents, which uses the same application
+ // then the new one.
+ SvtModuleOptions::EFactory eOldApp = SvtModuleOptions::ClassifyFactoryByModel(xModel);
+ SvtModuleOptions::EFactory eNewApp = SvtModuleOptions::ClassifyFactoryByURL (m_aURL.Complete, m_lMediaDescriptor.getAsConstPropertyValueList());
+
+ aReadLock.unlock();
+ // <- SAFE ..................................
+
+ if (eOldApp != eNewApp)
+ return css::uno::Reference< css::frame::XFrame >();
+
+ // OK this task seams to be useable for recycling
+ // But we should mark it as such - means set an action lock.
+ // Otherwhise it would be used more then ones or will be destroyed
+ // by a close() or terminate() request.
+ // But if such lock already exist ... it means this task is used for
+ // any other operation already. Don't use it then.
+ css::uno::Reference< css::document::XActionLockable > xLock(xTask, css::uno::UNO_QUERY);
+
+ // ? no lock interface ?
+ // Might its an external written frame implementation :-(
+ // Use it ... but it can fail if its not synchronized with our processes.
+ if (!xLock.is())
+ return xTask;
+
+ // Otherwhise we have to look for any other existing lock.
+ if (xLock->isActionLocked())
+ return css::uno::Reference< css::frame::XFrame >();
+
+ // SAFE -> ..................................
+ WriteGuard aWriteLock(m_aLock);
+ if (!m_aTargetLock.setResource(xLock))
+ return css::uno::Reference< css::frame::XFrame >();
+ aWriteLock.unlock();
+ // <- SAFE ..................................
+
+ return xTask;
+}
+
+/*-----------------------------------------------
+ 15.08.2003 12:39
+-----------------------------------------------*/
+void LoadEnv::impl_reactForLoadingState()
+ throw(LoadEnvException, css::uno::RuntimeException)
+{
+ /*TODO reset action locks */
+
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ m_aTargetLock.freeResource();
+
+ if (m_bLoaded)
+ {
+ // Bring the new loaded document to front (if allowed!).
+ // Note: We show new created frames here only.
+ // We dont hide already visible frames here ...
+ css::uno::Reference< css::awt::XWindow > xWindow = m_xTargetFrame->getContainerWindow();
+ sal_Bool bHidden = m_lMediaDescriptor.getUnpackedValueOrDefault(::framework::constant::MediaDescriptor::PROP_HIDDEN, sal_False);
+
+ if (!bHidden)
+ {
+ xWindow->setVisible(sal_True);
+ css::uno::Reference< css::awt::XTopWindow > xTopWindow(xWindow, css::uno::UNO_QUERY);
+ if(xTopWindow.is())
+ xTopWindow->toFront();
+ }
+
+ ::rtl::OUString sFrameName = m_lMediaDescriptor.getUnpackedValueOrDefault(::framework::constant::MediaDescriptor::PROP_FRAMENAME, ::rtl::OUString());
+ if (TargetHelper::isValidNameForFrame(sFrameName))
+ m_xTargetFrame->setName(sFrameName);
+ }
+ else
+ if (m_bReactivateControllerOnError)
+ {
+ // Try to reactivate the old document (if any exists!)
+ css::uno::Reference< css::frame::XController > xOldDoc = m_xTargetFrame->getController();
+ // clear does not depend from reactivation state of a might existing old document!
+ // We must make shure, that a might following getTargetComponent() call does not return
+ // the old document!
+ m_xTargetFrame.clear();
+ if (xOldDoc.is())
+ {
+ sal_Bool bReactivated = xOldDoc->suspend(sal_False);
+ if (!bReactivated)
+ throw LoadEnvException(LoadEnvException::ID_COULD_NOT_REACTIVATE_CONTROLLER);
+ m_bReactivateControllerOnError = sal_False;
+ }
+ }
+ else
+ {
+ // close empty frames
+ css::uno::Reference< css::util::XCloseable > xCloseable (m_xTargetFrame, css::uno::UNO_QUERY);
+ css::uno::Reference< css::lang::XComponent > xDisposable(m_xTargetFrame, css::uno::UNO_QUERY);
+
+ try
+ {
+ if (xCloseable.is())
+ xCloseable->close(sal_True);
+ else
+ if (xDisposable.is())
+ xDisposable->dispose();
+ }
+ catch(const css::util::CloseVetoException&)
+ {}
+ catch(const css::lang::DisposedException&)
+ {}
+ m_xTargetFrame.clear();
+ }
+
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+} // namespace framework