You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by ar...@apache.org on 2013/02/26 13:43:34 UTC
svn commit: r1450154 - in
/openoffice/devtools/sdk-examples/trunk/cpp/cppbindings/ConnectionAwareClient:
./ src/ src/Makefile src/main.cxx
Author: arielch
Date: Tue Feb 26 12:43:34 2013
New Revision: 1450154
URL: http://svn.apache.org/r1450154
Log:
Add example for connection aware client in C++
Added:
openoffice/devtools/sdk-examples/trunk/cpp/cppbindings/ConnectionAwareClient/
openoffice/devtools/sdk-examples/trunk/cpp/cppbindings/ConnectionAwareClient/src/
openoffice/devtools/sdk-examples/trunk/cpp/cppbindings/ConnectionAwareClient/src/Makefile (with props)
openoffice/devtools/sdk-examples/trunk/cpp/cppbindings/ConnectionAwareClient/src/main.cxx
Added: openoffice/devtools/sdk-examples/trunk/cpp/cppbindings/ConnectionAwareClient/src/Makefile
URL: http://svn.apache.org/viewvc/openoffice/devtools/sdk-examples/trunk/cpp/cppbindings/ConnectionAwareClient/src/Makefile?rev=1450154&view=auto
==============================================================================
--- openoffice/devtools/sdk-examples/trunk/cpp/cppbindings/ConnectionAwareClient/src/Makefile (added)
+++ openoffice/devtools/sdk-examples/trunk/cpp/cppbindings/ConnectionAwareClient/src/Makefile Tue Feb 26 12:43:34 2013
@@ -0,0 +1,125 @@
+#**************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+#**************************************************************
+
+# On *nix can be overridden with
+# make PRJ=$OO_SDK_HOME
+PRJ=../../../../..
+SETTINGS=$(PRJ)/settings
+
+include $(SETTINGS)/settings.mk
+include $(SETTINGS)/std.mk
+include $(SETTINGS)/dk.mk
+
+# Define non-platform/compiler specific settings
+APP_NAME=ConnectionAwareClient
+MAINTARGET=$(APP_NAME)_Example
+
+#this should be in odk/settings/std.mk
+OUT_DEPLOY=$(OUT)/deploy
+
+OUT_APP_INC=$(OUT_INC)/$(APP_NAME)
+OUT_APP_GEN=$(OUT_MISC)/$(APP_NAME)
+OUT_APP_OBJ=$(OUT_OBJ)/$(APP_NAME)
+OUT_APP_LIB=$(SHAREDLIB_OUT)/$(APP_NAME)
+OUT_APP_BIN=$(OUT_BIN)/$(APP_NAME)
+OUT_APP_DEPLOY=$(OUT_DEPLOY)/$(APP_NAME)
+
+
+CONNECTION_URL=socket,host=localhost,port=2083;urp;
+# Allow deploying the extension when running it
+ENV_USER_INSTALL=-env:"UserInstallation=$(URLPREFIX)$(OUT_APP_DEPLOY)"
+ENV_OFFICE_TYPES=-env:URE_MORE_TYPES=$(URLPREFIX)$(OFFICE_TYPES)
+OFFICE_START_OPTIONS=-nologo -nofirststartwizard -norestore -quickstart=no
+OXT_DEPLOYEDFLAG=$(OUT_COMP_GEN)/so_deployed_$(COMP_NAME).flag
+
+
+CXXFILES = main.cxx
+
+OBJFILES = $(patsubst %.cxx,$(OUT_APP_OBJ)/%.$(OBJ_EXT),$(CXXFILES))
+# remove in 4.0
+ifneq "$(DEBUG)" ""
+ CC_DEFINES+=-DOSL_DEBUG_LEVEL=3
+endif
+
+# Targets
+.PHONY: ALL StartAOOListening
+ALL : \
+ $(MAINTARGET)
+
+include $(SETTINGS)/stdtarget.mk
+
+
+$(OUT_APP_OBJ)/%.$(OBJ_EXT) : %.cxx $(SDKTYPEFLAG)
+ -$(MKDIR) $(subst /,$(PS),$(@D))
+ $(CC) $(CC_FLAGS) $(STL_INCLUDES) $(CC_INCLUDES) -I$(OUT_APP_INC) $(CC_DEFINES) $(CC_OUTPUT_SWITCH)$(subst /,$(PS),$@) $<
+
+$(OUT_APP_BIN)/_$(APP_NAME)$(EXE_EXT) : $(OBJFILES)
+ -$(MKDIR) $(subst /,$(PS),$(@D))
+ -$(MKDIR) $(subst /,$(PS),$(OUT_APP_GEN))
+ifeq "$(OS)" "WIN"
+ $(LINK) $(EXE_LINK_FLAGS) /OUT:$@ /MAP:$(OUT_APP_GEN)/$(basename $(@F)).map \
+ $(OBJFILES) $(CPPUHELPERLIB) $(CPPULIB) $(SALHELPERLIB) $(SALLIB) $(STLPORTLIB)
+else
+ $(LINK) $(EXE_LINK_FLAGS) $(LINK_LIBS) -o $@ $(OBJFILES) \
+ $(CPPUHELPERLIB) $(CPPULIB) $(SALHELPERLIB) $(SALLIB) $(STLPORTLIB) $(STDC++LIB) $(CPPUHELPERDYLIB) $(CPPUDYLIB) $(SALHELPERDYLIB) $(SALDYLIB)
+ifeq "$(OS)" "MACOSX"
+ $(INSTALL_NAME_URELIBS_BIN) $@
+endif
+endif
+
+$(OUT_APP_BIN)/$(APP_NAME)$(EXE_EXT) : $(OUT_APP_BIN)/_$(APP_NAME)$(EXE_EXT)
+ -$(MKDIR) $(subst /,$(PS),$(@D))
+ $(COPY) $(subst /,$(PS),$(BIN_DIR)/unoapploader$(EXE_EXT)) $(subst /,$(PS),$@)
+# workaround for touch problem under Windows with full qualified paths
+ make -t $@
+
+$(OUT_APP_BIN)/$(TEST_DOC) : $(TEST_DOC)
+ -$(MKDIR) $(subst /,$(PS),$(@D))
+ $(COPY) $(subst /,$(PS),$<) $(subst /,$(PS),$@)
+
+
+$(MAINTARGET) : $(OUT_APP_BIN)/$(APP_NAME)$(EXE_EXT)
+ @echo --------------------------------------------------------------------------------
+ @echo Please use the following command to execute the example!
+ @echo -
+ @echo $(MAKE) $(APP_NAME).run
+ @echo --------------------------------------------------------------------------------
+
+StartAOOListening:
+ -$(MKDIR) $(subst /,$(PS),$(OUT_APP_DEPLOY))
+ "$(OFFICE_PROGRAM_PATH)$(PS)soffice" \
+ $(OFFICE_START_OPTIONS) \
+ $(ENV_USER_INSTALL) \
+ -accept="$(CONNECTION_URL)" &
+
+$(APP_NAME).run: $(OUT_APP_BIN)/$(APP_NAME)$(EXE_EXT) StartAOOListening
+ cd $(subst /,$(PS),$(OUT_APP_BIN)) && $(basename $@) \
+ $(ENV_OFFICE_TYPES) \
+ "uno:$(CONNECTION_URL)StarOffice.ComponentContext"
+
+.PHONY: clean
+clean :
+ -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_APP_INC))
+ -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_APP_GEN))
+ -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_APP_OBJ))
+ -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_APP_LIB))
+ -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_APP_BIN))
+ -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_APP_DEPLOY))
Propchange: openoffice/devtools/sdk-examples/trunk/cpp/cppbindings/ConnectionAwareClient/src/Makefile
------------------------------------------------------------------------------
svn:eol-style = native
Added: openoffice/devtools/sdk-examples/trunk/cpp/cppbindings/ConnectionAwareClient/src/main.cxx
URL: http://svn.apache.org/viewvc/openoffice/devtools/sdk-examples/trunk/cpp/cppbindings/ConnectionAwareClient/src/main.cxx?rev=1450154&view=auto
==============================================================================
--- openoffice/devtools/sdk-examples/trunk/cpp/cppbindings/ConnectionAwareClient/src/main.cxx (added)
+++ openoffice/devtools/sdk-examples/trunk/cpp/cppbindings/ConnectionAwareClient/src/main.cxx Tue Feb 26 12:43:34 2013
@@ -0,0 +1,391 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#include <algorithm>
+#include <cstdlib>
+#include <functional>
+#include <iostream>
+#include <vector>
+
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/bootstrap.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <osl/process.h>
+#include <rtl/instance.hxx>
+#include <rtl/ref.hxx>
+#include <sal/main.h>
+
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/bridge/XBridgeFactory.hpp>
+#include <com/sun/star/connection/XConnector.hpp>
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <com/sun/star/util/XModifiable.hpp>
+
+#define C2U( constAsciiStr ) \
+ ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( constAsciiStr ) ) )
+
+namespace css = ::com::sun::star;
+using namespace osl;
+
+namespace connection_aware_client
+{
+ static std::ostream &
+ operator<<( std::ostream &stream, const rtl::OUString &rStr )
+ {
+ return stream << rtl::OUStringToOString( rStr, RTL_TEXTENCODING_UTF8 ).getStr();
+ }
+
+ static std::ostream &
+ operator<<( std::ostream &stream, const css::uno::Exception &e )
+ {
+ return stream << e.Message;
+ }
+
+ struct UnoConnUrl
+ {
+ rtl::OUString Connection;
+ rtl::OUString Object;
+ };
+
+ static bool lcl_ParseUnoUrl( const rtl::OUString &sUrl, UnoConnUrl &url )
+ {
+ // must start with "uno:"
+ if ( sUrl.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "uno:" ) != 0 ) )
+ return false;
+
+ sal_Int32 nIndex = sizeof( "uno:" ) - 1;
+
+ url.Connection = sUrl.getToken( 0, sal_Unicode( ';' ), nIndex );
+ // there should be an initial object
+ if ( nIndex == -1 )
+ return false;
+
+ // protocol must be "urp"
+ rtl::OUString sProtocol = sUrl.getToken( 0, sal_Unicode( ';' ), nIndex );
+ if ( nIndex == -1 || !sProtocol.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "urp" ) ) )
+ return false;
+
+ url.Object = sUrl.getToken( 0, sal_Unicode( ';' ), nIndex );
+
+ return url.Object.getLength() > 0 /* && nIndex == -1 */;
+ }
+
+ typedef ::cppu::WeakImplHelper1< css::lang::XEventListener > RemoteConnection_Base;
+
+ class RemoteConnection
+ : protected ::cppu::BaseMutex, public RemoteConnection_Base
+ {
+ private:
+ css::uno::Reference< css::uno::XComponentContext > m_xLocalContext;
+ css::uno::Reference< css::lang::XComponent > m_xBridge;
+ css::uno::Reference< css::uno::XInterface > m_xRemoteObject;
+ UnoConnUrl m_aUnoURL;
+ public:
+ RemoteConnection(
+ const css::uno::Reference< css::uno::XComponentContext > &xLocalContext,
+ const UnoConnUrl &url );
+ ~RemoteConnection();
+
+ void close();
+
+ void SAL_CALL disposing( const css::lang::EventObject &aEvent )
+ throw ( css::uno::RuntimeException );
+
+ css::uno::Reference< css::uno::XInterface > getRemoteObject();
+ };
+}
+
+using namespace connection_aware_client;
+
+RemoteConnection::RemoteConnection(
+ const css::uno::Reference< css::uno::XComponentContext > &xLocalContext,
+ const UnoConnUrl &url )
+ : RemoteConnection_Base()
+ , m_xLocalContext( xLocalContext )
+ , m_xBridge()
+ , m_xRemoteObject()
+ , m_aUnoURL( url )
+{
+ OSL_TRACE( "RemoteConnection::RemoteConnection" );
+}
+
+RemoteConnection::~RemoteConnection()
+{
+ OSL_TRACE( "RemoteConnection::~RemoteConnection" );
+}
+
+void RemoteConnection::close()
+{
+ OSL_TRACE( "RemoteConnection::close" );
+ osl::MutexGuard aGuard( m_aMutex );
+ if ( m_xBridge.is() )
+ {
+ m_xBridge->removeEventListener( this );
+ m_xBridge.clear();
+ m_xRemoteObject.clear();
+ }
+}
+
+void SAL_CALL
+RemoteConnection::disposing( const css::lang::EventObject &aEvent )
+throw ( css::uno::RuntimeException )
+{
+ OSL_TRACE( "RemoteConnection::disposing" );
+
+ osl::MutexGuard aGuard( m_aMutex );
+ OSL_ENSURE( aEvent.Source == m_xBridge, "Different source object!" );
+
+ m_xBridge.clear();
+ m_xRemoteObject.clear();
+}
+
+css::uno::Reference< css::uno::XInterface >
+RemoteConnection::getRemoteObject()
+{
+ OSL_TRACE( "RemoteConnection::getRemoteObject" );
+
+ osl::ResettableMutexGuard aGuard( m_aMutex );
+ css::uno::Reference< css::uno::XInterface > xRemoteObject = m_xRemoteObject;
+ css::uno::Reference< css::bridge::XBridge > xBridge( m_xBridge, css::uno::UNO_QUERY );
+ css::uno::Reference< css::uno::XComponentContext > xContext = m_xLocalContext;
+ aGuard.clear();
+
+ if ( xRemoteObject.is() || !xContext.is() )
+ return xRemoteObject;
+
+ if ( !xBridge.is() )
+ {
+ try
+ {
+ css::uno::Reference< css::connection::XConnector > xConnector(
+ xContext->getServiceManager()->createInstanceWithContext(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.connection.Connector" ) ),
+ xContext ), css::uno::UNO_QUERY );
+
+ css::uno::Reference< css::connection::XConnection > xConnection(
+ xConnector->connect( m_aUnoURL.Connection ) );
+
+ css::uno::Reference< css::bridge::XBridgeFactory > xBridgeFactory(
+ xContext->getServiceManager()->createInstanceWithContext(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.bridge.BridgeFactory" ) ),
+ xContext ), css::uno::UNO_QUERY );
+
+ xBridge.set(
+ xBridgeFactory->createBridge(
+ rtl::OUString(),
+ C2U( "urp" ),
+ xConnection,
+ css::uno::Reference< css::bridge::XInstanceProvider>() ) );
+
+ css::uno::Reference< css::lang::XComponent > xBridgeComp(
+ xBridge, css::uno::UNO_QUERY_THROW );
+ xBridgeComp->addEventListener( this );
+
+ aGuard.reset();
+ m_xBridge = xBridgeComp;
+ aGuard.clear();
+ }
+ catch ( const css::uno::Exception &e )
+ {
+ std::cerr << "getRemoteObject() caugth an exception: " << e << '\n';
+ }
+ }
+
+ if ( xBridge.is() )
+ {
+ try
+ {
+ xRemoteObject.set(
+ xBridge->getInstance(
+ m_aUnoURL.Object ),
+ css::uno::UNO_QUERY_THROW );
+ }
+ catch ( const css::uno::Exception &e )
+ {
+ std::cerr << "getRemoteObject() caugth an exception: " << e << '\n';
+ }
+
+ aGuard.reset();
+ m_xRemoteObject = xRemoteObject;
+ aGuard.clear();
+ }
+
+ return xRemoteObject;
+}
+
+
+static css::uno::Reference< css::uno::XInterface >
+testRemoteContext(
+ const css::uno::Reference< css::uno::XComponentContext > &xContext )
+{
+ try
+ {
+ css::uno::Reference< css::frame::XComponentLoader > xLoader(
+ xContext->getServiceManager()->createInstanceWithContext(
+ C2U( "com.sun.star.frame.Desktop" ), xContext ),
+ css::uno::UNO_QUERY_THROW );
+
+ css::uno::Reference< css::text::XTextDocument > xDoc(
+ xLoader->loadComponentFromURL(
+ C2U( "private:factory/swriter" ),
+ C2U( "_default" ),
+ css::frame::FrameSearchFlag::ALL,
+ css::uno::Sequence< css::beans::PropertyValue >() ),
+ css::uno::UNO_QUERY_THROW );
+
+ css::uno::Reference< css::text::XText > xText( xDoc->getText() );
+ xText->setString( C2U( "Hello world!" ) );
+
+ // change the modified flag to close the document without interaction
+ css::uno::Reference< css::util::XModifiable > xModified(
+ xDoc, css::uno::UNO_QUERY_THROW );
+ xModified->setModified( sal_False );
+
+ return xLoader;
+ }
+ catch ( const css::uno::Exception &e )
+ {
+ std::cerr << "getRemoteObject() caugth an exception: " << e << '\n';
+ }
+
+ return 0;
+}
+
+
+SAL_IMPLEMENT_MAIN_WITH_ARGS( argc, argv )
+{
+ oslProcessError eError;
+ sal_Int32 n = osl_getCommandArgCount( );
+ if ( n != 2 )
+ {
+ rtl::OUString sProgFile;
+ sal_Int32 nLen;
+ eError = osl_getExecutableFile( &sProgFile.pData );
+
+ if ( eError == osl_Process_E_None && ( nLen = sProgFile.getLength( ) ) )
+ n = sProgFile.lastIndexOf( sal_Unicode( '/' ) );
+
+ if ( n != -1 && n < nLen )
+ sProgFile = sProgFile.copy( ++n );
+
+ std::cerr << "Usage:\n\t" << sProgFile << "-env:URE_MORE_TYPES=<path to offapi.rdb> <UNO url>\n";
+
+ return EXIT_FAILURE;
+ }
+
+ // In this example, the second argument should contain a UNO connection URL
+ // to connect to the remote server running in the UNO executable launched
+ // in server mode.
+ UnoConnUrl aUrl;
+ rtl::OUString sUrl;
+ eError = osl_getCommandArg( 1, &sUrl.pData );
+
+ if ( eError != osl_Process_E_None ||
+ !sUrl.getLength() ||
+ !lcl_ParseUnoUrl( sUrl, aUrl ) )
+ {
+ std::cerr << "You must specify a valid UNO connection URL\n";
+ return EXIT_FAILURE;
+ }
+
+ std::cout << "Make sure OpenOffice is running and listening for connections!\n";
+ std::cout << "Press ENTER to start the test...";
+ std::cin.get();
+
+ // get the local component context
+ css::uno::Reference< css::uno::XComponentContext > xLocalContext;
+ try
+ {
+ xLocalContext.set(
+ cppu::defaultBootstrap_InitialComponentContext() );
+ }
+ catch ( const css::uno::Exception &e )
+ {
+ std::cerr << "Exception bootstrapping URE! " << e << '\n';
+ return EXIT_FAILURE;
+ }
+
+ // Hold a reference to the connection so that it lives during this function
+ rtl::Reference< RemoteConnection > aConnection(
+ new RemoteConnection( xLocalContext, aUrl ) );
+
+ // get the object exported by the remote server
+ css::uno::Reference< css::uno::XComponentContext > xRemoteContext(
+ aConnection->getRemoteObject(), css::uno::UNO_QUERY );
+
+ if ( !xRemoteContext.is() )
+ {
+ std::cerr << "Cannot get remote component context!\n";
+ }
+ else
+ {
+ css::uno::Reference< css::frame::XDesktop > xDesktop(
+ testRemoteContext( xRemoteContext ),
+ css::uno::UNO_QUERY_THROW );
+
+ if ( xDesktop.is() )
+ {
+ std::cout << "Press ENTER to terminate the Desktop...";
+ std::cin.get();
+ bool bTerminate = true;
+ try
+ {
+ xDesktop->terminate();
+ }
+ catch ( const css::uno::Exception &e )
+ {
+ std::cerr << "Cannot terminate the Desktop!\n";
+ bTerminate = false;
+ }
+
+ if ( bTerminate )
+ {
+ // wait a little until it terminates
+ std::cout << "The office is terminating...\nPress ENTER to test the bridge...";
+ std::cin.get();
+
+ // retreiving the remote context should fail now:
+ // the bridge gets disposed, we try to reconnect,
+ // but there is no office instance listening
+ xRemoteContext.set( aConnection->getRemoteObject(), css::uno::UNO_QUERY );
+ if ( xRemoteContext.is() )
+ std::cerr << "Got a remote context with a ternimated office!\n";
+ }
+ }
+ }
+
+ std::cout << "Press ENTER to finish the example...";
+ std::cin.get();
+
+ aConnection->close();
+ aConnection.clear();
+
+ return EXIT_SUCCESS;
+}
+