2009-05-15 14:06:56 +02:00
|
|
|
/*************************************************************************
|
|
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
|
|
*
|
|
|
|
* Copyright 2009 by Sun Microsystems, Inc.
|
|
|
|
*
|
|
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
|
|
*
|
|
|
|
* $RCSfile: code,v $
|
|
|
|
*
|
|
|
|
* $Revision: 1.4 $
|
|
|
|
*
|
|
|
|
* This file is part of OpenOffice.org.
|
|
|
|
*
|
|
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
|
|
* only, as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* OpenOffice.org 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 version 3 for more details
|
|
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
|
|
* <http://www.openoffice.org/license.html>
|
|
|
|
* for a copy of the LGPLv3 License.
|
|
|
|
************************************************************************/
|
|
|
|
|
|
|
|
#include "precompiled_configmgr.hxx"
|
|
|
|
#include "sal/config.h"
|
|
|
|
|
2009-07-28 15:30:19 +02:00
|
|
|
#include <algorithm>
|
2009-08-04 10:36:31 +02:00
|
|
|
#include <list>
|
2009-05-15 14:06:56 +02:00
|
|
|
|
2009-10-01 16:48:00 +02:00
|
|
|
#include "com/sun/star/beans/Optional.hpp"
|
|
|
|
#include "com/sun/star/beans/UnknownPropertyException.hpp"
|
|
|
|
#include "com/sun/star/beans/XPropertySet.hpp"
|
2009-09-08 16:25:16 +02:00
|
|
|
#include "com/sun/star/container/NoSuchElementException.hpp"
|
2009-10-01 16:48:00 +02:00
|
|
|
#include "com/sun/star/lang/WrappedTargetException.hpp"
|
|
|
|
#include "com/sun/star/lang/XMultiComponentFactory.hpp"
|
|
|
|
#include "com/sun/star/uno/Any.hxx"
|
|
|
|
#include "com/sun/star/uno/Exception.hpp"
|
2009-09-08 14:59:07 +02:00
|
|
|
#include "com/sun/star/uno/Reference.hxx"
|
2009-05-15 14:06:56 +02:00
|
|
|
#include "com/sun/star/uno/RuntimeException.hpp"
|
2009-09-25 14:47:45 +02:00
|
|
|
#include "com/sun/star/uno/XComponentContext.hpp"
|
2009-05-28 10:19:30 +02:00
|
|
|
#include "com/sun/star/uno/XInterface.hpp"
|
2009-09-08 14:59:07 +02:00
|
|
|
#include "osl/diagnose.h"
|
2009-05-15 14:06:56 +02:00
|
|
|
#include "osl/file.hxx"
|
|
|
|
#include "rtl/bootstrap.hxx"
|
2009-05-19 10:49:37 +02:00
|
|
|
#include "rtl/ref.hxx"
|
2009-05-15 14:06:56 +02:00
|
|
|
#include "rtl/string.h"
|
2009-10-01 16:48:00 +02:00
|
|
|
#include "rtl/textenc.h"
|
2009-05-15 14:06:56 +02:00
|
|
|
#include "rtl/ustring.h"
|
|
|
|
#include "rtl/ustring.hxx"
|
|
|
|
#include "sal/types.h"
|
|
|
|
|
|
|
|
#include "components.hxx"
|
2009-08-07 10:25:27 +02:00
|
|
|
#include "data.hxx"
|
2009-09-23 16:07:30 +02:00
|
|
|
#include "modifications.hxx"
|
2009-05-15 14:06:56 +02:00
|
|
|
#include "node.hxx"
|
2009-09-08 14:59:07 +02:00
|
|
|
#include "parsemanager.hxx"
|
2009-09-21 13:14:11 +02:00
|
|
|
#include "rootaccess.hxx"
|
2009-09-07 17:10:16 +02:00
|
|
|
#include "writemodfile.hxx"
|
2009-09-08 14:59:07 +02:00
|
|
|
#include "xcdparser.hxx"
|
|
|
|
#include "xcuparser.hxx"
|
|
|
|
#include "xcsparser.hxx"
|
2009-05-15 14:06:56 +02:00
|
|
|
|
|
|
|
namespace configmgr {
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
namespace css = com::sun::star;
|
|
|
|
|
2009-08-04 10:36:31 +02:00
|
|
|
struct UnresolvedListItem {
|
|
|
|
rtl::OUString name;
|
2009-09-08 14:59:07 +02:00
|
|
|
rtl::Reference< ParseManager > manager;
|
2009-08-04 10:36:31 +02:00
|
|
|
|
2009-08-18 10:00:07 +02:00
|
|
|
UnresolvedListItem(
|
2009-09-08 14:59:07 +02:00
|
|
|
rtl::OUString const & theName,
|
|
|
|
rtl::Reference< ParseManager > theManager):
|
|
|
|
name(theName), manager(theManager) {}
|
2009-08-04 10:36:31 +02:00
|
|
|
};
|
|
|
|
|
2009-08-18 10:00:07 +02:00
|
|
|
typedef std::list< UnresolvedListItem > UnresolvedList;
|
2009-08-04 10:36:31 +02:00
|
|
|
|
2009-10-01 16:48:00 +02:00
|
|
|
void parseXcsFile(rtl::OUString const & url, int layer, Data * data)
|
2009-09-08 16:25:16 +02:00
|
|
|
SAL_THROW((
|
2009-10-01 10:18:13 +02:00
|
|
|
css::container::NoSuchElementException, css::uno::RuntimeException))
|
2009-09-08 16:25:16 +02:00
|
|
|
{
|
2009-09-08 14:59:07 +02:00
|
|
|
OSL_VERIFY(
|
|
|
|
rtl::Reference< ParseManager >(
|
|
|
|
new ParseManager(url, new XcsParser(layer, data)))->parse());
|
|
|
|
}
|
|
|
|
|
2009-10-01 16:48:00 +02:00
|
|
|
void parseXcuFile(rtl::OUString const & url, int layer, Data * data)
|
2009-09-08 16:25:16 +02:00
|
|
|
SAL_THROW((
|
2009-10-01 10:18:13 +02:00
|
|
|
css::container::NoSuchElementException, css::uno::RuntimeException))
|
2009-09-08 16:25:16 +02:00
|
|
|
{
|
2009-09-08 14:59:07 +02:00
|
|
|
OSL_VERIFY(
|
|
|
|
rtl::Reference< ParseManager >(
|
2009-10-01 16:48:00 +02:00
|
|
|
new ParseManager(url, new XcuParser(layer, data)))->parse());
|
2009-09-08 14:59:07 +02:00
|
|
|
}
|
|
|
|
|
2009-07-23 12:42:37 +02:00
|
|
|
rtl::OUString expand(rtl::OUString const & str) {
|
|
|
|
rtl::OUString s(str);
|
|
|
|
rtl::Bootstrap::expandMacros(s); //TODO: detect failure
|
2009-08-07 10:25:27 +02:00
|
|
|
return s;
|
2009-07-23 12:42:37 +02:00
|
|
|
}
|
|
|
|
|
2009-09-25 14:47:45 +02:00
|
|
|
static bool singletonCreated = false;
|
|
|
|
static Components * singleton; // leaks
|
|
|
|
|
2009-07-10 11:20:28 +02:00
|
|
|
}
|
|
|
|
|
2009-09-25 14:47:45 +02:00
|
|
|
void Components::initSingleton(
|
|
|
|
css::uno::Reference< css::uno::XComponentContext > const & context)
|
|
|
|
{
|
|
|
|
OSL_ASSERT(context.is());
|
|
|
|
if (!singletonCreated) {
|
|
|
|
singletonCreated = true;
|
|
|
|
singleton = new Components(context);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Components & Components::getSingleton() {
|
|
|
|
OSL_ASSERT(singletonCreated);
|
|
|
|
if (singleton == 0) {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"configmgr no Components singleton")),
|
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
|
|
|
return *singleton;
|
2009-07-10 11:20:28 +02:00
|
|
|
}
|
|
|
|
|
2009-07-22 14:41:57 +02:00
|
|
|
bool Components::allLocales(rtl::OUString const & locale) {
|
|
|
|
return locale.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("*"));
|
2009-07-10 11:20:28 +02:00
|
|
|
}
|
|
|
|
|
2009-09-22 17:15:42 +02:00
|
|
|
rtl::Reference< Node > Components::resolvePathRepresentation(
|
|
|
|
rtl::OUString const & pathRepresentation, Path * path,
|
|
|
|
int * finalizedLayer) const
|
2009-07-14 17:10:46 +02:00
|
|
|
{
|
2009-09-22 17:15:42 +02:00
|
|
|
return data_.resolvePathRepresentation(
|
|
|
|
pathRepresentation, path, finalizedLayer);
|
2009-07-14 17:10:46 +02:00
|
|
|
}
|
|
|
|
|
2009-07-22 14:41:57 +02:00
|
|
|
rtl::Reference< Node > Components::getTemplate(
|
|
|
|
int layer, rtl::OUString const & fullName) const
|
2009-07-08 17:25:16 +02:00
|
|
|
{
|
2009-08-07 10:25:27 +02:00
|
|
|
return data_.getTemplate(layer, fullName);
|
2009-07-22 14:41:57 +02:00
|
|
|
}
|
|
|
|
|
2009-09-21 13:14:11 +02:00
|
|
|
void Components::addRootAccess(rtl::Reference< RootAccess > const & access) {
|
|
|
|
roots_.insert(access.get());
|
|
|
|
}
|
|
|
|
|
|
|
|
void Components::removeRootAccess(RootAccess * access) {
|
|
|
|
roots_.erase(access);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Components::initGlobalBroadcaster(
|
2009-09-23 16:07:30 +02:00
|
|
|
Modifications const & modifications,
|
2009-09-21 13:14:11 +02:00
|
|
|
rtl::Reference< RootAccess > const & exclude, Broadcaster * broadcaster)
|
|
|
|
{
|
2009-09-23 16:07:30 +02:00
|
|
|
//TODO: Iterate only over roots w/ listeners:
|
2009-09-21 13:14:11 +02:00
|
|
|
for (WeakRootSet::iterator i(roots_.begin()); i != roots_.end(); ++i) {
|
2009-09-22 10:36:09 +02:00
|
|
|
rtl::Reference< RootAccess > root;
|
|
|
|
if ((*i)->acquireCounting() > 1) {
|
|
|
|
root.set(*i); // must not throw
|
|
|
|
}
|
|
|
|
(*i)->releaseNondeleting();
|
|
|
|
if (root.is()) {
|
|
|
|
if (root != exclude) {
|
2009-09-23 16:07:30 +02:00
|
|
|
Path path(root->getAbsolutePath());
|
2009-09-23 17:48:27 +02:00
|
|
|
Modifications::Node const * mods = &modifications.getRoot();
|
2009-09-23 16:07:30 +02:00
|
|
|
for (Path::iterator j(path.begin()); j != path.end(); ++j) {
|
2009-09-23 17:48:27 +02:00
|
|
|
Modifications::Node::Children::const_iterator k(
|
2009-09-23 16:07:30 +02:00
|
|
|
mods->children.find(*j));
|
|
|
|
if (k == mods->children.end()) {
|
|
|
|
mods = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
mods = &k->second;
|
|
|
|
}
|
|
|
|
//TODO: If the complete tree of which root is a part is deleted,
|
|
|
|
// or replaced, mods will be null, but some of the listeners
|
|
|
|
// from within root should probably fire nonetheless:
|
|
|
|
if (mods != 0) {
|
2009-10-15 16:31:42 +02:00
|
|
|
root->initBroadcaster(*mods, broadcaster);
|
2009-09-23 16:07:30 +02:00
|
|
|
}
|
2009-09-22 10:36:09 +02:00
|
|
|
}
|
2009-09-21 13:14:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-22 17:15:42 +02:00
|
|
|
void Components::addModification(Path const & path) {
|
2009-09-21 13:14:11 +02:00
|
|
|
data_.modifications.add(path);
|
2009-07-22 14:41:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Components::writeModifications() {
|
2009-10-01 16:48:00 +02:00
|
|
|
writeModFile(*this, getModificationFileUrl(), data_);
|
2009-07-08 17:25:16 +02:00
|
|
|
}
|
|
|
|
|
2009-11-13 16:02:09 +01:00
|
|
|
void Components::insertExtensionXcsFile(
|
|
|
|
bool shared, rtl::OUString const & fileUri)
|
|
|
|
{
|
2009-09-08 16:25:16 +02:00
|
|
|
try {
|
2009-11-13 16:02:09 +01:00
|
|
|
parseXcsFile(fileUri, shared ? 9 : 13, &data_);
|
2009-09-08 16:25:16 +02:00
|
|
|
} catch (css::container::NoSuchElementException & e) {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
2009-11-13 16:02:09 +01:00
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"insertExtensionXcsFile does not exist: ")) +
|
2009-09-08 16:25:16 +02:00
|
|
|
e.Message),
|
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
2009-07-24 16:56:06 +02:00
|
|
|
}
|
|
|
|
|
2009-11-13 16:02:09 +01:00
|
|
|
void Components::insertExtensionXcuFile(
|
|
|
|
bool shared, rtl::OUString const & fileUri)
|
|
|
|
{
|
2009-09-08 16:25:16 +02:00
|
|
|
try {
|
2009-11-13 16:02:09 +01:00
|
|
|
parseXcuFile(fileUri, shared ? 10 : 14, &data_);
|
2009-09-08 16:25:16 +02:00
|
|
|
} catch (css::container::NoSuchElementException & e) {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
2009-11-13 16:02:09 +01:00
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"insertExtensionXcuFile does not exist: ")) +
|
2009-09-08 16:25:16 +02:00
|
|
|
e.Message),
|
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
2009-07-24 16:56:06 +02:00
|
|
|
}
|
|
|
|
|
2009-10-01 16:48:00 +02:00
|
|
|
css::beans::Optional< css::uno::Any > Components::getExternalValue(
|
2009-10-02 15:12:00 +02:00
|
|
|
rtl::OUString const & descriptor)
|
2009-10-01 16:48:00 +02:00
|
|
|
{
|
|
|
|
sal_Int32 i = descriptor.indexOf(' ');
|
|
|
|
if (i <= 0) {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM("bad external value descriptor ")) +
|
|
|
|
descriptor),
|
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
|
|
|
//TODO: Do not make calls with mutex locked:
|
2009-10-02 15:12:00 +02:00
|
|
|
rtl::OUString name(descriptor.copy(0, i));
|
|
|
|
ExternalServices::iterator j(externalServices_.find(name));
|
|
|
|
if (j == externalServices_.end()) {
|
|
|
|
css::uno::Reference< css::uno::XInterface > service;
|
|
|
|
try {
|
|
|
|
service = css::uno::Reference< css::lang::XMultiComponentFactory >(
|
|
|
|
context_->getServiceManager(), css::uno::UNO_SET_THROW)->
|
|
|
|
createInstanceWithContext(name, context_);
|
|
|
|
} catch (css::uno::RuntimeException &) {
|
|
|
|
// Assuming these exceptions are real errors:
|
|
|
|
throw;
|
|
|
|
} catch (css::uno::Exception & e) {
|
|
|
|
// Assuming these exceptions indicate that the service is not
|
|
|
|
// installed:
|
|
|
|
OSL_TRACE(
|
|
|
|
"createInstance(%s) failed with %s",
|
|
|
|
rtl::OUStringToOString(name, RTL_TEXTENCODING_UTF8).getStr(),
|
|
|
|
rtl::OUStringToOString(
|
|
|
|
e.Message, RTL_TEXTENCODING_UTF8).getStr());
|
|
|
|
}
|
|
|
|
css::uno::Reference< css::beans::XPropertySet > propset;
|
|
|
|
if (service.is()) {
|
|
|
|
propset = css::uno::Reference< css::beans::XPropertySet >(
|
|
|
|
service, css::uno::UNO_QUERY_THROW);
|
|
|
|
}
|
|
|
|
j = externalServices_.insert(
|
|
|
|
ExternalServices::value_type(name, propset)).first;
|
2009-10-01 16:48:00 +02:00
|
|
|
}
|
|
|
|
css::beans::Optional< css::uno::Any > value;
|
2009-10-02 15:12:00 +02:00
|
|
|
if (j->second.is()) {
|
2009-10-01 16:48:00 +02:00
|
|
|
try {
|
2009-10-02 15:12:00 +02:00
|
|
|
if (!(j->second->getPropertyValue(descriptor.copy(i + 1)) >>=
|
2009-10-01 16:48:00 +02:00
|
|
|
value))
|
|
|
|
{
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"cannot obtain external value through ")) +
|
|
|
|
descriptor),
|
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
|
|
|
} catch (css::beans::UnknownPropertyException & e) {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"unknwon external value descriptor ID: ")) +
|
|
|
|
e.Message),
|
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
} catch (css::lang::WrappedTargetException & e) {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"cannot obtain external value: ")) +
|
|
|
|
e.Message),
|
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2009-09-25 14:47:45 +02:00
|
|
|
Components::Components(
|
|
|
|
css::uno::Reference< css::uno::XComponentContext > const & context):
|
|
|
|
context_(context)
|
|
|
|
{
|
|
|
|
OSL_ASSERT(context.is());
|
2009-07-22 14:41:57 +02:00
|
|
|
parseXcsXcuLayer(
|
|
|
|
0,
|
|
|
|
expand(
|
|
|
|
rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM("$OOO_BASE_DIR/share/registry"))));
|
|
|
|
parseModuleLayer(
|
|
|
|
2,
|
|
|
|
expand(
|
|
|
|
rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"$OOO_BASE_DIR/share/registry/modules"))));
|
|
|
|
parseResLayer(
|
|
|
|
3,
|
|
|
|
expand(
|
|
|
|
rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM("$OOO_BASE_DIR/share/registry"))));
|
|
|
|
parseXcsXcuLayer(
|
|
|
|
4,
|
|
|
|
expand(
|
|
|
|
rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"$BRAND_BASE_DIR/share/registry"))));
|
|
|
|
parseModuleLayer(
|
|
|
|
6,
|
|
|
|
expand(
|
|
|
|
rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"$BRAND_BASE_DIR/share/registry/modules"))));
|
2009-07-24 16:56:06 +02:00
|
|
|
parseXcsXcuLayer( //TODO: migrate
|
2009-07-22 14:41:57 +02:00
|
|
|
7,
|
|
|
|
expand(
|
|
|
|
rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
2009-08-27 17:03:38 +02:00
|
|
|
"${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("uno")
|
|
|
|
":UNO_SHARED_PACKAGES_CACHE}/registry/"
|
|
|
|
"com.sun.star.comp.deployment.configuration."
|
2009-07-22 14:41:57 +02:00
|
|
|
"PackageRegistryBackend/registry"))));
|
2009-07-24 16:56:06 +02:00
|
|
|
parseXcsXcuIniLayer(
|
2009-07-22 14:41:57 +02:00
|
|
|
9,
|
2009-07-24 16:56:06 +02:00
|
|
|
expand(
|
|
|
|
rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
2009-08-27 17:03:38 +02:00
|
|
|
"${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("uno")
|
|
|
|
":UNO_SHARED_PACKAGES_CACHE}/registry/"
|
|
|
|
"com.sun.star.comp.deployment.configuration."
|
2009-11-13 16:15:18 +01:00
|
|
|
"PackageRegistryBackend/configmgr.ini"))));
|
2009-07-24 16:56:06 +02:00
|
|
|
parseXcsXcuLayer( //TODO: migrate
|
|
|
|
11,
|
2009-07-22 14:41:57 +02:00
|
|
|
expand(
|
|
|
|
rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
2009-08-27 17:03:38 +02:00
|
|
|
"${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("uno")
|
|
|
|
":UNO_USER_PACKAGES_CACHE}/registry/"
|
|
|
|
"com.sun.star.comp.deployment.configuration."
|
2009-07-22 14:41:57 +02:00
|
|
|
"PackageRegistryBackend/registry"))));
|
2009-07-24 16:56:06 +02:00
|
|
|
parseXcsXcuIniLayer(
|
|
|
|
13,
|
|
|
|
expand(
|
|
|
|
rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
2009-08-27 17:03:38 +02:00
|
|
|
"${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("uno")
|
|
|
|
":UNO_USER_PACKAGES_CACHE}/registry/"
|
|
|
|
"com.sun.star.comp.deployment.configuration."
|
2009-11-13 16:15:18 +01:00
|
|
|
"PackageRegistryBackend/configmgr.ini"))));
|
2009-10-14 10:12:41 +02:00
|
|
|
try {
|
|
|
|
parseModificationLayer();
|
|
|
|
} catch (css::uno::Exception & e) { //TODO: more specific exception catching
|
|
|
|
// Silently ignore unreadable parts of a corrupted
|
|
|
|
// registrymodifications.xcu file, instead of completely preventing OOo
|
|
|
|
// from starting:
|
|
|
|
OSL_TRACE(
|
|
|
|
"configmgr error reading user modification layer: %s",
|
|
|
|
rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr());
|
|
|
|
}
|
2009-05-20 17:20:08 +02:00
|
|
|
}
|
|
|
|
|
2009-07-22 14:41:57 +02:00
|
|
|
Components::~Components() {}
|
|
|
|
|
2009-08-04 10:36:31 +02:00
|
|
|
void Components::parseFiles(
|
|
|
|
int layer, rtl::OUString const & extension,
|
2009-10-01 16:48:00 +02:00
|
|
|
void (* parseFile)(rtl::OUString const &, int, Data *),
|
2009-08-04 10:36:31 +02:00
|
|
|
rtl::OUString const & url, bool recursive)
|
|
|
|
{
|
|
|
|
osl::Directory dir(url);
|
|
|
|
switch (dir.open()) {
|
|
|
|
case osl::FileBase::E_None:
|
|
|
|
break;
|
|
|
|
case osl::FileBase::E_NOENT:
|
|
|
|
if (!recursive) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// fall through
|
|
|
|
default:
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM("cannot open directory ")) +
|
|
|
|
url),
|
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
2009-07-30 17:24:11 +02:00
|
|
|
}
|
2009-08-04 10:36:31 +02:00
|
|
|
for (;;) {
|
|
|
|
osl::DirectoryItem i;
|
|
|
|
osl::FileBase::RC rc = dir.getNextItem(i, SAL_MAX_UINT32);
|
|
|
|
if (rc == osl::FileBase::E_NOENT) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (rc != osl::FileBase::E_None) {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM("cannot iterate directory ")) +
|
|
|
|
url),
|
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
|
|
|
osl::FileStatus stat(
|
|
|
|
FileStatusMask_Type | FileStatusMask_FileName |
|
|
|
|
FileStatusMask_FileURL);
|
|
|
|
if (i.getFileStatus(stat) != osl::FileBase::E_None) {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM("cannot stat in directory ")) +
|
|
|
|
url),
|
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
|
|
|
if (stat.getFileType() == osl::FileStatus::Directory) { //TODO: symlinks
|
|
|
|
parseFiles(layer, extension, parseFile, stat.getFileURL(), true);
|
|
|
|
} else {
|
|
|
|
rtl::OUString file(stat.getFileName());
|
|
|
|
if (file.getLength() >= extension.getLength() &&
|
|
|
|
file.match(extension, file.getLength() - extension.getLength()))
|
|
|
|
{
|
2009-09-08 16:25:16 +02:00
|
|
|
try {
|
2009-10-01 16:48:00 +02:00
|
|
|
(*parseFile)(stat.getFileURL(), layer, &data_);
|
2009-09-08 16:25:16 +02:00
|
|
|
} catch (css::container::NoSuchElementException & e) {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"stat'ed file does not exist: ")) +
|
|
|
|
e.Message),
|
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
2009-08-04 10:36:31 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Components::parseFileList(
|
2009-10-01 16:48:00 +02:00
|
|
|
int layer, void (* parseFile)(rtl::OUString const &, int, Data *),
|
2009-08-04 10:36:31 +02:00
|
|
|
rtl::OUString const & urls, rtl::Bootstrap const & ini)
|
|
|
|
{
|
|
|
|
for (sal_Int32 i = 0;;) {
|
|
|
|
rtl::OUString url(urls.getToken(0, ' ', i));
|
|
|
|
if (url.getLength() != 0) {
|
|
|
|
ini.expandMacrosFrom(url); //TODO: detect failure
|
2009-09-08 16:25:16 +02:00
|
|
|
try {
|
2009-10-01 16:48:00 +02:00
|
|
|
(*parseFile)(url, layer, &data_);
|
2009-09-08 16:25:16 +02:00
|
|
|
} catch (css::container::NoSuchElementException & e) {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"stat'ed file does not exist: ")) +
|
|
|
|
e.Message),
|
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
2009-08-04 10:36:31 +02:00
|
|
|
}
|
|
|
|
if (i == -1) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-08-07 10:25:27 +02:00
|
|
|
void Components::parseXcdFiles(int layer, rtl::OUString const & url) {
|
2009-07-22 14:41:57 +02:00
|
|
|
osl::Directory dir(url);
|
|
|
|
switch (dir.open()) {
|
|
|
|
case osl::FileBase::E_None:
|
|
|
|
break;
|
|
|
|
case osl::FileBase::E_NOENT:
|
2009-08-04 10:36:31 +02:00
|
|
|
return;
|
2009-07-22 14:41:57 +02:00
|
|
|
default:
|
2009-07-08 17:25:16 +02:00
|
|
|
throw css::uno::RuntimeException(
|
2009-07-22 14:41:57 +02:00
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM("cannot open directory ")) +
|
|
|
|
url),
|
2009-07-08 17:25:16 +02:00
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
2009-08-04 10:36:31 +02:00
|
|
|
UnresolvedList unres;
|
2009-09-08 14:59:07 +02:00
|
|
|
XcdParser::Dependencies deps;
|
2009-07-22 14:41:57 +02:00
|
|
|
for (;;) {
|
|
|
|
osl::DirectoryItem i;
|
|
|
|
osl::FileBase::RC rc = dir.getNextItem(i, SAL_MAX_UINT32);
|
|
|
|
if (rc == osl::FileBase::E_NOENT) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (rc != osl::FileBase::E_None) {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM("cannot iterate directory ")) +
|
|
|
|
url),
|
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
|
|
|
osl::FileStatus stat(
|
|
|
|
FileStatusMask_Type | FileStatusMask_FileName |
|
|
|
|
FileStatusMask_FileURL);
|
|
|
|
if (i.getFileStatus(stat) != osl::FileBase::E_None) {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM("cannot stat in directory ")) +
|
|
|
|
url),
|
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
2009-08-04 10:36:31 +02:00
|
|
|
if (stat.getFileType() != osl::FileStatus::Directory) { //TODO: symlinks
|
2009-07-22 14:41:57 +02:00
|
|
|
rtl::OUString file(stat.getFileName());
|
2009-08-04 10:36:31 +02:00
|
|
|
if (file.getLength() >= RTL_CONSTASCII_LENGTH(".xcd") &&
|
|
|
|
file.matchAsciiL(
|
|
|
|
RTL_CONSTASCII_STRINGPARAM(".xcd"),
|
|
|
|
file.getLength() - RTL_CONSTASCII_LENGTH(".xcd")))
|
2009-07-22 14:41:57 +02:00
|
|
|
{
|
2009-08-04 10:36:31 +02:00
|
|
|
rtl::OUString name(
|
|
|
|
file.copy(
|
|
|
|
0, file.getLength() - RTL_CONSTASCII_LENGTH(".xcd")));
|
2009-09-08 16:25:16 +02:00
|
|
|
rtl::Reference< ParseManager > manager;
|
|
|
|
try {
|
|
|
|
manager = new ParseManager(
|
2009-10-01 16:48:00 +02:00
|
|
|
stat.getFileURL(), new XcdParser(layer, deps, &data_));
|
2009-09-08 16:25:16 +02:00
|
|
|
} catch (css::container::NoSuchElementException & e) {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"stat'ed file does not exist: ")) +
|
|
|
|
e.Message),
|
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
|
|
|
}
|
2009-09-08 14:59:07 +02:00
|
|
|
if (manager->parse()) {
|
2009-08-04 10:36:31 +02:00
|
|
|
deps.insert(name);
|
|
|
|
} else {
|
2009-09-08 14:59:07 +02:00
|
|
|
unres.push_back(UnresolvedListItem(name, manager));
|
2009-08-04 10:36:31 +02:00
|
|
|
}
|
2009-07-13 14:54:09 +02:00
|
|
|
}
|
2009-07-08 17:25:16 +02:00
|
|
|
}
|
|
|
|
}
|
2009-08-04 10:36:31 +02:00
|
|
|
while (!unres.empty()) {
|
|
|
|
bool resolved = false;
|
|
|
|
for (UnresolvedList::iterator i(unres.begin()); i != unres.end();) {
|
2009-09-08 14:59:07 +02:00
|
|
|
if (i->manager->parse()) {
|
2009-08-04 10:36:31 +02:00
|
|
|
deps.insert(i->name);
|
2009-08-18 10:00:07 +02:00
|
|
|
unres.erase(i++);
|
2009-08-04 10:36:31 +02:00
|
|
|
resolved = true;
|
|
|
|
} else {
|
|
|
|
++i;
|
|
|
|
}
|
2009-07-24 16:56:06 +02:00
|
|
|
}
|
2009-08-04 10:36:31 +02:00
|
|
|
if (!resolved) {
|
|
|
|
throw css::uno::RuntimeException(
|
|
|
|
(rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"xcd: unresolved dependencies in ")) +
|
|
|
|
url),
|
|
|
|
css::uno::Reference< css::uno::XInterface >());
|
2009-07-24 16:56:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-07-22 14:41:57 +02:00
|
|
|
void Components::parseXcsXcuLayer(int layer, rtl::OUString const & url) {
|
2009-08-07 10:25:27 +02:00
|
|
|
parseXcdFiles(layer, url);
|
2009-07-22 14:41:57 +02:00
|
|
|
parseFiles(
|
|
|
|
layer, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".xcs")),
|
2009-09-08 14:59:07 +02:00
|
|
|
&parseXcsFile,
|
2009-07-22 14:41:57 +02:00
|
|
|
url + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/schema")), false);
|
|
|
|
parseFiles(
|
|
|
|
layer + 1, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".xcu")),
|
2009-09-08 14:59:07 +02:00
|
|
|
&parseXcuFile,
|
2009-07-22 14:41:57 +02:00
|
|
|
url + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/data")), false);
|
2009-05-15 14:06:56 +02:00
|
|
|
}
|
|
|
|
|
2009-07-24 16:56:06 +02:00
|
|
|
void Components::parseXcsXcuIniLayer(int layer, rtl::OUString const & url) {
|
|
|
|
//TODO: rtl::Bootstrap::getFrom "first trie[s] to retrieve the value via the
|
|
|
|
// global function"
|
|
|
|
rtl::Bootstrap ini(url);
|
|
|
|
rtl::OUString urls;
|
|
|
|
if (ini.getFrom(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SCHEMA")), urls))
|
|
|
|
{
|
2009-09-08 14:59:07 +02:00
|
|
|
parseFileList(layer, &parseXcsFile, urls, ini);
|
2009-07-24 16:56:06 +02:00
|
|
|
}
|
|
|
|
if (ini.getFrom(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DATA")), urls))
|
|
|
|
{
|
2009-09-08 14:59:07 +02:00
|
|
|
parseFileList(layer + 1, &parseXcuFile, urls, ini);
|
2009-07-24 16:56:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-07-22 14:41:57 +02:00
|
|
|
void Components::parseModuleLayer(int layer, rtl::OUString const & url) {
|
|
|
|
parseFiles(
|
|
|
|
layer, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".xcu")),
|
2009-09-08 14:59:07 +02:00
|
|
|
&parseXcuFile, url, false);
|
2009-05-15 14:06:56 +02:00
|
|
|
}
|
|
|
|
|
2009-07-22 14:41:57 +02:00
|
|
|
void Components::parseResLayer(int layer, rtl::OUString const & url) {
|
2009-08-04 10:36:31 +02:00
|
|
|
rtl::OUString resUrl(
|
|
|
|
url + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/res")));
|
2009-08-07 10:25:27 +02:00
|
|
|
parseXcdFiles(layer, resUrl);
|
2009-07-22 14:41:57 +02:00
|
|
|
parseFiles(
|
|
|
|
layer, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".xcu")),
|
2009-09-08 14:59:07 +02:00
|
|
|
&parseXcuFile, resUrl, false);
|
2009-05-15 14:06:56 +02:00
|
|
|
}
|
|
|
|
|
2009-07-08 17:25:16 +02:00
|
|
|
rtl::OUString Components::getModificationFileUrl() const {
|
|
|
|
return expand(
|
|
|
|
rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
2009-08-27 17:03:38 +02:00
|
|
|
"${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE("bootstrap")
|
|
|
|
":UserInstallation}/user/registrymodifications.xcu")));
|
2009-07-08 17:25:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Components::parseModificationLayer() {
|
2009-09-08 16:25:16 +02:00
|
|
|
try {
|
2009-10-01 16:48:00 +02:00
|
|
|
parseXcuFile(getModificationFileUrl(), Data::NO_LAYER, &data_);
|
2009-09-08 16:25:16 +02:00
|
|
|
} catch (css::container::NoSuchElementException &) {
|
|
|
|
OSL_TRACE(
|
|
|
|
"configmgr user registrymodifications.xcu does not (yet) exist");
|
2009-10-14 10:12:41 +02:00
|
|
|
// Migrate old user layer data (can be removed once migration is no
|
|
|
|
// longer relevant; also see hack for xsi namespace in XmlReader
|
|
|
|
// constructor):
|
|
|
|
parseFiles(
|
|
|
|
Data::NO_LAYER, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".xcu")),
|
|
|
|
&parseXcuFile,
|
|
|
|
expand(
|
|
|
|
rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
|
|
"${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE("bootstrap")
|
|
|
|
":UserInstallation}/user/registry/data"))),
|
|
|
|
false);
|
2009-09-08 14:59:07 +02:00
|
|
|
}
|
2009-07-02 14:21:36 +02:00
|
|
|
}
|
|
|
|
|
2009-05-15 14:06:56 +02:00
|
|
|
}
|