summaryrefslogtreecommitdiffstats
path: root/framework/source/fwi/jobs/configaccess.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'framework/source/fwi/jobs/configaccess.cxx')
-rw-r--r--framework/source/fwi/jobs/configaccess.cxx184
1 files changed, 184 insertions, 0 deletions
diff --git a/framework/source/fwi/jobs/configaccess.cxx b/framework/source/fwi/jobs/configaccess.cxx
new file mode 100644
index 000000000..fde891293
--- /dev/null
+++ b/framework/source/fwi/jobs/configaccess.cxx
@@ -0,0 +1,184 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+#include <jobs/configaccess.hxx>
+#include <services.h>
+
+#include <com/sun/star/configuration/theDefaultProvider.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <utility>
+
+#include <tools/diagnose_ex.h>
+
+namespace framework{
+
+/**
+ @short open the configuration of this job
+ @descr We open the configuration of this job only. Not the whole package or the whole
+ job set. We are interested on our own properties only.
+ We set the opened configuration access as our member. So any following method,
+ which needs cfg access, can use it. That prevent us against multiple open/close requests.
+ But you can use this method to upgrade an already opened configuration too.
+
+ @param eMode
+ force opening of the configuration access in readonly or in read/write mode
+ */
+ConfigAccess::ConfigAccess( /*IN*/ css::uno::Reference< css::uno::XComponentContext > xContext,
+ /*IN*/ OUString sRoot )
+ : m_xContext (std::move( xContext))
+ , m_sRoot (std::move( sRoot ))
+ , m_eMode ( E_CLOSED )
+{
+}
+
+/**
+ @short last chance to close an open configuration access point
+ @descr In case our user forgot to close this configuration point
+ in the right way, normally he will run into some trouble -
+ e.g. losing data.
+ */
+ConfigAccess::~ConfigAccess()
+{
+ close();
+}
+
+/**
+ @short return the internal mode of this instance
+ @descr May be the outside user need any information about successfully opened
+ or closed config access point objects. He can control the internal mode to do so.
+
+ @return The internal open state of this object.
+ */
+ConfigAccess::EOpenMode ConfigAccess::getMode() const
+{
+ std::unique_lock g(m_mutex);
+ return m_eMode;
+}
+
+/**
+ @short open the configuration access in the specified mode
+ @descr We set the opened configuration access as our member. So any following method,
+ which needs cfg access, can use it. That prevent us against multiple open/close requests.
+ But you can use this method to upgrade an already opened configuration too.
+ It's possible to open a config access in READONLY mode first and "open" it at a second
+ time within the mode READWRITE. Then we will upgrade it. Downgrade will be possible too.
+
+ But note: closing will be done explicitly by calling method close() ... not by
+ downgrading with mode CLOSED!
+
+ @param eMode
+ force (re)opening of the configuration access in readonly or in read/write mode
+ */
+void ConfigAccess::open( /*IN*/ EOpenMode eMode )
+{
+ std::unique_lock g(m_mutex);
+
+ // check if configuration is already open in the right mode.
+ // By the way: Don't allow closing by using this method!
+ if ( eMode == E_CLOSED || m_eMode == eMode )
+ return;
+
+ // We have to close the old access point without any question here.
+ // It will be open again using the new mode.
+ // can be called without checks! It does the checks by itself ...
+ // e.g. for already closed or not opened configuration.
+ // Flushing of all made changes will be done here too.
+ closeImpl();
+
+ // create the configuration provider, which provides sub access points
+ css::uno::Reference< css::lang::XMultiServiceFactory > xConfigProvider = css::configuration::theDefaultProvider::get(m_xContext);
+ css::beans::PropertyValue aParam;
+ aParam.Name = "nodepath";
+ aParam.Value <<= m_sRoot;
+
+ css::uno::Sequence< css::uno::Any > lParams{ css::uno::Any(aParam) };
+
+ // open it
+ try
+ {
+ if (eMode==E_READONLY)
+ m_xConfig = xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGREADACCESS , lParams);
+ else
+ if (eMode==E_READWRITE)
+ m_xConfig = xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGUPDATEACCESS, lParams);
+ }
+ catch(const css::uno::Exception&)
+ {
+ TOOLS_INFO_EXCEPTION("fwk", "open config");
+ }
+
+ m_eMode = E_CLOSED;
+ if (m_xConfig.is())
+ m_eMode = eMode;
+}
+
+/**
+ @short close the internal opened configuration access and flush all changes
+ @descr It checks, if the given access is valid and react in the right way.
+ It flushes all changes ... so nobody else must know this state.
+ */
+void ConfigAccess::close()
+{
+ std::unique_lock g(m_mutex);
+ closeImpl();
+}
+
+void ConfigAccess::closeImpl()
+{
+ // check already closed configuration
+ if (m_xConfig.is())
+ {
+ css::uno::Reference< css::util::XChangesBatch > xFlush(m_xConfig, css::uno::UNO_QUERY);
+ if (xFlush.is())
+ xFlush->commitChanges();
+ m_xConfig.clear();
+ m_eMode = E_CLOSED;
+ }
+}
+
+/**
+ @short provides an access to the internal wrapped configuration access
+ @descr It's not allowed to safe this c++ (!) reference outside. You have
+ to use it directly. Further you must use our public lock member m_aLock
+ to synchronize your code with our internal structures and our interface
+ methods. Acquire it before you call cfg() and release it afterwards immediately.
+
+ E.g.: ConfigAccess aAccess(...);
+ Guard aReadLock(aAccess.m_aLock);
+ Reference< XPropertySet > xSet(aAccess.cfg(), UNO_QUERY);
+ Any aProp = xSet->getPropertyValue("...");
+ aReadLock.unlock();
+
+ @attention During this time it's not allowed to call the methods open() or close()!
+ Otherwise you will change your own referenced config access. Anything will
+ be possible then.
+
+ @return A c++(!) reference to the uno instance of the configuration access point.
+ */
+const css::uno::Reference< css::uno::XInterface >& ConfigAccess::cfg()
+{
+ // must be synchronized from outside!
+ // => no lock here ...
+ return m_xConfig;
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */