diff options
author | Ivo Hinkelmann <ihi@openoffice.org> | 2006-12-19 10:46:28 +0000 |
---|---|---|
committer | Ivo Hinkelmann <ihi@openoffice.org> | 2006-12-19 10:46:28 +0000 |
commit | 7d58b49c17546d64245ad2a3124ac706c7ceb018 (patch) | |
tree | 16f6e7db4370d31f9faebcdcbfbca204391a8bbc /desktop/source/pkgchk/unopkg | |
parent | c908ebcd20ef53286925c9b3f568245ed224e1c5 (diff) |
INTEGRATION: CWS jl46 (1.1.2); FILE ADDED
2006/12/06 07:54:10 jl 1.1.2.6: #i69173# removed warning
2006/12/06 07:34:26 jl 1.1.2.5: #i69173# removed warning
2006/11/22 13:45:17 ihi 1.1.2.4: #i69173# Add support for URLs
2006/10/30 09:55:26 jl 1.1.2.3: #69173# message when another unopkg is running
2006/10/27 15:08:20 jl 1.1.2.2: #69173# message when another unopkg is running
2006/10/26 15:09:58 jl 1.1.2.1: #i69173# build unopkg separately because it is now a pure gui application
Diffstat (limited to 'desktop/source/pkgchk/unopkg')
-rw-r--r-- | desktop/source/pkgchk/unopkg/unopkg_misc.cxx | 499 |
1 files changed, 499 insertions, 0 deletions
diff --git a/desktop/source/pkgchk/unopkg/unopkg_misc.cxx b/desktop/source/pkgchk/unopkg/unopkg_misc.cxx new file mode 100644 index 000000000000..71fe8156ee6c --- /dev/null +++ b/desktop/source/pkgchk/unopkg/unopkg_misc.cxx @@ -0,0 +1,499 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: unopkg_misc.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: ihi $ $Date: 2006-12-19 11:46:28 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 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 + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_desktop.hxx" + +#include "deployment.hrc" +#include "../unopkg_shared.h" +#include "../../deployment/gui/dp_gui.hrc" +#include "../../app/lockfile.hxx" +#include "vcl/svapp.hxx" +#include "vcl/msgbox.hxx" +#include "rtl/strbuf.hxx" +#include "rtl/ustrbuf.hxx" +#include "osl/process.h" +#include "osl/file.h" +#include "osl/thread.hxx" +#include "cppuhelper/servicefactory.hxx" +#include "cppuhelper/component_context.hxx" +#include "ucbhelper/contentbroker.hxx" +#include "ucbhelper/configurationkeys.hxx" +#include "unotools/processfactory.hxx" +#include "unotools/configmgr.hxx" +#include "com/sun/star/beans/XPropertySet.hpp" +#include <stdio.h> + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::ucb; + +namespace unopkg { + + +::rtl::OString toString( OptionInfo const * info ) +{ + OSL_ASSERT( info != 0 ); + ::rtl::OStringBuffer buf; + buf.append( RTL_CONSTASCII_STRINGPARAM("--") ); + buf.append( info->m_name, info->m_name_length ); + if (info->m_short_option != '\0') + { + buf.append( RTL_CONSTASCII_STRINGPARAM(" (short -") ); + buf.append( static_cast< char >(info->m_short_option) ); + buf.append( ')' ); + } + if (info->m_has_argument) + buf.append( RTL_CONSTASCII_STRINGPARAM(" <argument>") ); + return buf.makeStringAndClear(); +} + +//============================================================================== +OptionInfo const * getOptionInfo( + OptionInfo const * list, + OUString const & opt, sal_Unicode copt ) +{ + for ( ; list->m_name != 0; ++list ) + { + OptionInfo const & option_info = *list; + if (opt.getLength() > 0) + { + if (opt.equalsAsciiL( + option_info.m_name, option_info.m_name_length ) && + (copt == '\0' || copt == option_info.m_short_option)) + { + return &option_info; + } + } + else + { + OSL_ASSERT( copt != '\0' ); + if (copt == option_info.m_short_option) + { + return &option_info; + } + } + } + OSL_ENSURE( 0, ::rtl::OUStringToOString( + opt, osl_getThreadTextEncoding() ).getStr() ); + return 0; +} + +//============================================================================== +bool isOption( OptionInfo const * option_info, sal_uInt32 * pIndex ) +{ + OSL_ASSERT( option_info != 0 ); + if (osl_getCommandArgCount() <= *pIndex) + return false; + + OUString arg; + osl_getCommandArg( *pIndex, &arg.pData ); + sal_Int32 len = arg.getLength(); + + if (len < 2 || arg[ 0 ] != '-') + return false; + + if (len == 2 && arg[ 1 ] == option_info->m_short_option) + { + ++(*pIndex); +#if OSL_DEBUG_LEVEL > 1 + OSL_TRACE( + __FILE__": identified option \'%c\'", option_info->m_short_option ); +#endif + return true; + } + if (arg[ 1 ] == '-' && rtl_ustr_ascii_compare( + arg.pData->buffer + 2, option_info->m_name ) == 0) + { + ++(*pIndex); +#if OSL_DEBUG_LEVEL > 1 + OSL_TRACE( __FILE__": identified option \'%s\'", option_info->m_name ); +#endif + return true; + } + return false; +} + +//============================================================================== +bool readArgument( + OUString * pValue, OptionInfo const * option_info, sal_uInt32 * pIndex ) +{ + if (isOption( option_info, pIndex )) + { + if (*pIndex < osl_getCommandArgCount()) + { + OSL_ASSERT( pValue != 0 ); + osl_getCommandArg( *pIndex, &pValue->pData ); +#if OSL_DEBUG_LEVEL > 1 + OSL_TRACE( + __FILE__": argument value: %s\n", + ::rtl::OUStringToOString( + *pValue, osl_getThreadTextEncoding() ).getStr() ); +#endif + ++(*pIndex); + return true; + } + --(*pIndex); + } + return false; +} + +//############################################################################## + +namespace { +struct ExecutableDir : public rtl::StaticWithInit< + const OUString, ExecutableDir> { + const OUString operator () () { + OUString path; + if (osl_getExecutableFile( &path.pData ) != osl_Process_E_None) { + throw RuntimeException( + OUSTR("cannot locate executable directory!"),0 ); + } + return path.copy( 0, path.lastIndexOf( '/' ) ); + } +}; +struct ProcessWorkingDir : public rtl::StaticWithInit< + const OUString, ProcessWorkingDir> { + const OUString operator () () { + OUString workingDir; + osl_getProcessWorkingDir( &workingDir.pData ); + return workingDir; + } +}; +} // anon namespace + +//============================================================================== +OUString const & getExecutableDir() +{ + return ExecutableDir::get(); +} + +//============================================================================== +OUString const & getProcessWorkingDir() +{ + return ProcessWorkingDir::get(); +} + +//============================================================================== +OUString makeAbsoluteFileUrl( + OUString const & sys_path, OUString const & base_url, bool throw_exc ) +{ + // system path to file url + OUString file_url; + oslFileError rc = osl_getFileURLFromSystemPath( sys_path.pData, &file_url.pData ); + if ( rc != osl_File_E_None) { + OUString tempPath; + if ( osl_getSystemPathFromFileURL( sys_path.pData, &tempPath.pData) == osl_File_E_None ) + { + file_url = sys_path; + } + else if (throw_exc) + { + throw RuntimeException( + OUSTR("cannot get file url from system path: ") + + sys_path, Reference< XInterface >() ); + } + } + + OUString abs; + if (osl_getAbsoluteFileURL( + base_url.pData, file_url.pData, &abs.pData ) != osl_File_E_None) + { + if (throw_exc) { + ::rtl::OUStringBuffer buf; + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( + "making absolute file url failed: \"") ); + buf.append( base_url ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( + "\" (base-url) and \"") ); + buf.append( file_url ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" (file-url)!") ); + throw RuntimeException( + buf.makeStringAndClear(), Reference< XInterface >() ); + } + return OUString(); + } + return abs[ abs.getLength() -1 ] == '/' + ? abs.copy( 0, abs.getLength() -1 ) : abs; +} + +//############################################################################## + +namespace { + +//------------------------------------------------------------------------------ +inline void printf_space( sal_Int32 space ) +{ + while (space--) + printf( " " ); +} + +//------------------------------------------------------------------------------ +void printf_line( + OUString const & name, OUString const & value, sal_Int32 level ) +{ + rtl_TextEncoding textenc = osl_getThreadTextEncoding(); + printf_space( level ); + printf( "%s: %s\n", + ::rtl::OUStringToOString( name, textenc ).getStr(), + ::rtl::OUStringToOString( value, textenc ).getStr() ); +} + +//------------------------------------------------------------------------------ +void printf_package( + Reference<deployment::XPackage> const & xPackage, + Reference<XCommandEnvironment> const & xCmdEnv, sal_Int32 level ) +{ + printf_line( OUSTR("Name"), xPackage->getName(), level ); + OUString version(xPackage->getVersion()); + if (version.getLength() != 0) + printf_line( OUSTR("Version"), version, level + 1 ); + printf_line( OUSTR("URL"), xPackage->getURL(), level + 1 ); + + beans::Optional< beans::Ambiguous<sal_Bool> > option( + xPackage->isRegistered( Reference<task::XAbortChannel>(), xCmdEnv ) ); + OUString value; + if (option.IsPresent) { + beans::Ambiguous<sal_Bool> const & reg = option.Value; + if (reg.IsAmbiguous) + value = OUSTR("unknown"); + else + value = reg.Value ? OUSTR("yes") : OUSTR("no"); + } + else + value = OUSTR("n/a"); + printf_line( OUSTR("is registered"), value, level + 1 ); + + const Reference<deployment::XPackageTypeInfo> xPackageType( + xPackage->getPackageType() ); + OSL_ASSERT( xPackageType.is() ); + if (xPackageType.is()) { + printf_line( OUSTR("Media-Type"), + xPackageType->getMediaType(), level + 1 ); + } + printf_line( OUSTR("Description"), xPackage->getDescription(), level + 1 ); + if (xPackage->isBundle()) { + Sequence< Reference<deployment::XPackage> > seq( + xPackage->getBundle( Reference<task::XAbortChannel>(), xCmdEnv ) ); + printf_space( level + 1 ); + printf( "bundled Packages: {\n" ); + printf_packages( seq, xCmdEnv, level + 2 ); + printf_space( level + 1 ); + printf( "}\n" ); + } +} + +} // anon namespace + +//============================================================================== +void printf_packages( + Sequence< Reference<deployment::XPackage> > const & seq, + Reference<XCommandEnvironment> const & xCmdEnv, sal_Int32 level ) +{ + sal_Int32 len = seq.getLength(); + Reference< deployment::XPackage > const * p = seq.getConstArray(); + if (len == 0) { + printf_space( level ); + printf( "<none>\n" ); + } + else { + for ( sal_Int32 pos = 0; pos < len; ++pos ) + printf_package( p[ pos ], xCmdEnv, level ); + } +} + +//############################################################################## + +namespace { + +//------------------------------------------------------------------------------ +Reference<XComponentContext> bootstrapStandAlone( + DisposeGuard & disposeGuard, bool /*verbose */) +{ + // bootstrap standalone UNO using types.rdb and services.rdb + // directly avoiding any rc entries + Reference<beans::XPropertySet> xProps( + ::cppu::createRegistryServiceFactory( + getExecutableDir() + OUSTR("/types.rdb"), + getExecutableDir() + OUSTR("/services.rdb"), + true /* read-only */ ), + UNO_QUERY_THROW ); + Reference<XComponentContext> xContext( + xProps->getPropertyValue( OUSTR("DefaultContext") ), + UNO_QUERY_THROW ); + // assure disposing of local component context: + disposeGuard.reset( + Reference<lang::XComponent>( xContext, UNO_QUERY ) ); + + // wrap component context to work on local configuration data only + const ::cppu::ContextEntry_Init contextEntries [] = { +#define CFG_PREFIX "/modules/com.sun.star.configuration/bootstrap/" + ::cppu::ContextEntry_Init( + OUSTR(CFG_PREFIX "BackendService"), + Any( OUSTR("com.sun.star.configuration.backend." + "LocalSingleBackend") ) ), + ::cppu::ContextEntry_Init( + OUSTR(CFG_PREFIX "BackendWrapper"), + Any( OUSTR("com.sun.star.configuration.backend." + "OnlineBackend") ) ), + ::cppu::ContextEntry_Init( + OUSTR(CFG_PREFIX "CacheUrl"), Any( OUString() ) ), + ::cppu::ContextEntry_Init( OUSTR(CFG_PREFIX "Offline"), Any() ), + ::cppu::ContextEntry_Init( + OUSTR("/implementations/com.sun.star.com.configuration." + "bootstrap.ComponentContext/isPassthrough"), + Any(true) ) + }; + xContext = ::cppu::createComponentContext( + contextEntries, ARLEN(contextEntries), xContext ); + + Reference<lang::XMultiServiceFactory> xServiceManager( + xContext->getServiceManager(), UNO_QUERY_THROW ); + // set global process service factory used by unotools config helpers + ::utl::setProcessServiceFactory( xServiceManager ); + + // initialize the ucbhelper ucb, + // because the package implementation uses it + Sequence<Any> ucb_args( 2 ); + ucb_args[ 0 ] <<= OUSTR(UCB_CONFIGURATION_KEY1_LOCAL); + ucb_args[ 1 ] <<= OUSTR(UCB_CONFIGURATION_KEY2_OFFICE); + if (! ::ucb::ContentBroker::initialize( xServiceManager, ucb_args )) + throw RuntimeException( OUSTR("cannot initialize UCB!"), 0 ); + + return xContext; +} + +//------------------------------------------------------------------------------ +Reference<XComponentContext> connectToOffice( + Reference<XComponentContext> const & xLocalComponentContext, + bool verbose ) +{ + Sequence<OUString> args( 3 ); + args[ 0 ] = OUSTR("-nologo"); + args[ 1 ] = OUSTR("-nodefault"); + + OUString pipeId( ::dp_misc::generateRandomPipeId() ); + ::rtl::OUStringBuffer buf; + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("-accept=pipe,name=") ); + buf.append( pipeId ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(";urp;") ); + args[ 2 ] = buf.makeStringAndClear(); + OUString appURL( getExecutableDir() + OUSTR("/soffice") ); + + if (verbose) + { + rtl_TextEncoding textenc = osl_getThreadTextEncoding(); + printf( "Raising process: %s\nArguments: -nologo -nodefault %s\n", + ::rtl::OUStringToOString( appURL, textenc ).getStr(), + ::rtl::OUStringToOString( args[ 2 ], textenc ).getStr() ); + } + + ::dp_misc::raiseProcess( appURL, args ); + + if (verbose) + printf( "Ok. Connecting..." ); + + OSL_ASSERT( buf.getLength() == 0 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("uno:pipe,name=") ); + buf.append( pipeId ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( + ";urp;StarOffice.ComponentContext") ); + Reference<XComponentContext> xRet( + ::dp_misc::resolveUnoURL( + buf.makeStringAndClear(), xLocalComponentContext ), + UNO_QUERY_THROW ); + if (verbose) + printf( "Ok.\n" ); + + return xRet; +} + +} // anon namespace + +//============================================================================== +Reference<XComponentContext> getUNO( + DisposeGuard & disposeGuard, bool verbose, bool bGui ) +{ + // hold lock during process runtime: + static ::desktop::Lockfile s_lockfile( false /* no IPC server */ ); + Reference<XComponentContext> xComponentContext( + bootstrapStandAlone( disposeGuard, verbose ) ); + if (::dp_misc::office_is_running()) { + xComponentContext.set( + connectToOffice( xComponentContext, verbose ) ); + } + else + { + if (! s_lockfile.check( 0 )) + { + //We show a message box or print to the console that there + //is another instance already running + if ( ! InitVCL( Reference<lang::XMultiServiceFactory>( + xComponentContext->getServiceManager(), + UNO_QUERY_THROW ) )) + throw RuntimeException( OUSTR("Cannot initialize VCL!"), + NULL ); + + { + ResId warnId(WARNINGBOX_CONCURRENTINSTANCE,DeploymentGuiResMgr::get() ); + WarningBox warn(NULL, warnId); + warn.SetText(::utl::ConfigManager::GetDirectConfigProperty( + ::utl::ConfigManager::PRODUCTNAME).get<OUString>()); + + warn.SetIcon(0); + if (bGui) + { + warn.Execute(); + } + else + { + ::rtl::OString osWarn = ::rtl::OUStringToOString( + warn.GetMessText(), osl_getThreadTextEncoding()); + fprintf(stdout,"\n%s\n\n", osWarn.getStr()); + } + } + DeInitVCL(); + throw RuntimeException( + OUSTR("Lock file indicates that a concurrent Office process " + "is running!"), Reference<XInterface>() ); + } + } + + return xComponentContext; +} + +} + |