${CMAKE_CURRENT_LIST_DIR}/remotepermissions.cpp
${CMAKE_CURRENT_LIST_DIR}/vfs.cpp
${CMAKE_CURRENT_LIST_DIR}/pinstate.cpp
- ${CMAKE_CURRENT_LIST_DIR}/plugin.cpp
${CMAKE_CURRENT_LIST_DIR}/syncfilestatus.cpp
)
-configure_file(${CMAKE_CURRENT_LIST_DIR}/vfspluginmetadata.json.in ${CMAKE_CURRENT_BINARY_DIR}/vfspluginmetadata.json)
+++ /dev/null
-/*
- * Copyright (C) by Dominik Schmidt <dschmidt@owncloud.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "plugin.h"
-
-#include "config.h"
-
-namespace OCC {
-
-PluginFactory::~PluginFactory() = default;
-
-QString pluginFileName(const QString &type, const QString &name)
-{
- return QStringLiteral("%1sync_%2_%3")
- .arg(QStringLiteral(APPLICATION_EXECUTABLE), type, name);
-}
-
-}
+++ /dev/null
-/*
- * Copyright (C) by Dominik Schmidt <dschmidt@owncloud.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#pragma once
-
-#include "ocsynclib.h"
-#include <QObject>
-
-namespace OCC {
-
-class OCSYNC_EXPORT PluginFactory
-{
-public:
- virtual ~PluginFactory();
- virtual QObject* create(QObject* parent) = 0;
-};
-
-template<class PluginClass>
-class DefaultPluginFactory : public PluginFactory
-{
-public:
- QObject* create(QObject *parent) override
- {
- return new PluginClass(parent);
- }
-};
-
-/// Return the expected name of a plugin, for use with QPluginLoader
-QString pluginFileName(const QString &type, const QString &name);
-
-}
-
-Q_DECLARE_INTERFACE(OCC::PluginFactory, "org.owncloud.PluginFactory")
*/
#include "vfs.h"
-#include "plugin.h"
#include "version.h"
#include "syncjournaldb.h"
using namespace OCC;
+using MetaObjectHash = QHash<QString, Vfs::Factory>;
+Q_GLOBAL_STATIC(MetaObjectHash, vfsFactoryHash);
+
+void Vfs::registerPlugin(const QString &name, Factory factory)
+{
+ Q_ASSERT(!vfsFactoryHash()->contains(name));
+ vfsFactoryHash()->insert(name, factory);
+}
+
Vfs::Vfs(QObject* parent)
: QObject(parent)
{
auto name = modeToPluginName(mode);
if (name.isEmpty())
return false;
- auto pluginPath = pluginFileName(QStringLiteral("vfs"), name);
- QPluginLoader loader(pluginPath);
- auto basemeta = loader.metaData();
- if (basemeta.isEmpty() || !basemeta.contains(QStringLiteral("IID"))) {
- qCDebug(lcPlugin) << "Plugin doesn't exist" << loader.fileName();
- return false;
- }
- if (basemeta[QStringLiteral("IID")].toString() != QLatin1String("org.owncloud.PluginFactory")) {
- qCWarning(lcPlugin) << "Plugin has wrong IID" << loader.fileName() << basemeta[QStringLiteral("IID")];
- return false;
- }
-
- auto metadata = basemeta[QStringLiteral("MetaData")].toObject();
- if (metadata[QStringLiteral("type")].toString() != QLatin1String("vfs")) {
- qCWarning(lcPlugin) << "Plugin has wrong type" << loader.fileName() << metadata[QStringLiteral("type")];
- return false;
- }
- if (metadata[QStringLiteral("version")].toString() != QStringLiteral(MIRALL_VERSION_STRING)) {
- qCWarning(lcPlugin) << "Plugin has wrong version" << loader.fileName() << metadata[QStringLiteral("version")];
- return false;
- }
-
- // Attempting to load the plugin is essential as it could have dependencies that
- // can't be resolved and thus not be available after all.
- if (!loader.load()) {
- qCWarning(lcPlugin) << "Plugin failed to load:" << loader.errorString();
+ if (!vfsFactoryHash()->contains(name)) {
+ qCDebug(lcPlugin) << "Plugin isn't registered:" << name;
return false;
}
auto name = modeToPluginName(mode);
if (name.isEmpty())
return nullptr;
- auto pluginPath = pluginFileName(QStringLiteral("vfs"), name);
if (!isVfsPluginAvailable(mode)) {
- qCCritical(lcPlugin) << "Could not load plugin: not existant or bad metadata" << pluginPath;
- return nullptr;
- }
-
- QPluginLoader loader(pluginPath);
- auto plugin = loader.instance();
- if (!plugin) {
- qCCritical(lcPlugin) << "Could not load plugin" << pluginPath << loader.errorString();
+ qCCritical(lcPlugin) << "Could not load plugin: not existant" << name;
return nullptr;
}
- auto factory = qobject_cast<PluginFactory *>(plugin);
+ const auto factory = vfsFactoryHash()->value(name);
if (!factory) {
- qCCritical(lcPlugin) << "Plugin" << loader.fileName() << "does not implement PluginFactory";
+ qCCritical(lcPlugin) << "Could not load plugin" << name;
return nullptr;
}
- auto vfs = std::unique_ptr<Vfs>(qobject_cast<Vfs *>(factory->create(nullptr)));
+ auto vfs = std::unique_ptr<Vfs>(qobject_cast<Vfs *>(factory()));
if (!vfs) {
- qCCritical(lcPlugin) << "Plugin" << loader.fileName() << "does not create a Vfs instance";
+ qCCritical(lcPlugin) << "Plugin" << name << "does not create a Vfs instance";
return nullptr;
}
- qCInfo(lcPlugin) << "Created VFS instance from plugin" << pluginPath;
+ qCInfo(lcPlugin) << "Created VFS instance for:" << name;
return vfs;
}
#pragma once
#include <QObject>
+#include <QCoreApplication>
#include <QScopedPointer>
#include <QSharedPointer>
using AvailabilityResult = Result<VfsItemAvailability, AvailabilityError>;
public:
+ using Factory = Vfs* (*)();
+ static void registerPlugin(const QString &name, Factory factory);
+
explicit Vfs(QObject* parent = nullptr);
virtual ~Vfs();
OCSYNC_EXPORT std::unique_ptr<Vfs> createVfsFromPlugin(Vfs::Mode mode);
} // namespace OCC
+
+#define OCC_DEFINE_VFS_FACTORY(name, Type) \
+ static_assert (std::is_base_of<OCC::Vfs, Type>::value, "Please define VFS factories only for OCC::Vfs subclasses"); \
+ namespace { \
+ void initPlugin() \
+ { \
+ OCC::Vfs::registerPlugin(QStringLiteral(name), []() -> OCC::Vfs * { return new Type; }); \
+ } \
+ Q_COREAPP_STARTUP_FUNCTION(initPlugin) \
+ }
creds/abstractcredentials.cpp
creds/credentialscommon.cpp
creds/keychainchunk.cpp
+ vfs/suffix/vfs_suffix.cpp
)
if(TOKEN_AUTH_ONLY)
else()
install(TARGETS ${synclib_NAME} DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/MacOS)
endif()
-
-
-add_subdirectory(vfs)
+++ /dev/null
-# Globbing for plugins has a problem with in-source builds
-# that create directories for the build.
-#file(GLOB VIRTUAL_FILE_SYSTEM_PLUGINS RELATIVE ${CMAKE_CURRENT_LIST_DIR} "*")
-
-list(APPEND VIRTUAL_FILE_SYSTEM_PLUGINS "suffix" "win")
-
-foreach(vfsPlugin ${VIRTUAL_FILE_SYSTEM_PLUGINS})
- set(vfsPluginPath ${vfsPlugin})
- get_filename_component(vfsPluginName ${vfsPlugin} NAME)
- if (NOT IS_ABSOLUTE ${vfsPlugin})
- set(vfsPluginPath "${CMAKE_CURRENT_LIST_DIR}/${vfsPlugin}")
- endif()
- if(NOT IS_DIRECTORY ${vfsPluginPath})
- continue()
- endif()
-
- add_subdirectory(${vfsPluginPath} ${vfsPluginName})
-
- if(UNIT_TESTING AND IS_DIRECTORY "${vfsPluginPath}/test")
- add_subdirectory("${vfsPluginPath}/test" "${vfsPluginName}_test")
- message(STATUS "Added vfsPlugin with tests: ${vfsPluginName}")
- else()
- message(STATUS "Added vfsPlugin without tests: ${vfsPluginName}")
- endif()
-endforeach()
+++ /dev/null
-add_library("${synclib_NAME}_vfs_suffix" SHARED
- vfs_suffix.cpp
-)
-
-target_link_libraries("${synclib_NAME}_vfs_suffix"
- "${synclib_NAME}"
-)
-
-set_target_properties("${synclib_NAME}_vfs_suffix" PROPERTIES
- LIBRARY_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY}
- RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY}
- PREFIX ""
- AUTOMOC TRUE
-)
-
-if(APPLE)
- # for being loadable when client run from build dir
- set(vfs_buildoutputdir "${BIN_OUTPUT_DIRECTORY}/${OWNCLOUD_OSX_BUNDLE}/Contents/PlugIns/")
- set_target_properties("${synclib_NAME}_vfs_suffix"
- PROPERTIES
- LIBRARY_OUTPUT_DIRECTORY ${vfs_buildoutputdir}
- RUNTIME_OUTPUT_DIRECTORY ${vfs_buildoutputdir}
- )
- # For being lodable when client run from install dir (after make macdeployqt)
- set(vfs_installdir "${LIB_INSTALL_DIR}/../PlugIns")
-else()
- set(vfs_installdir "${PLUGINDIR}")
-endif()
-
-INSTALL(TARGETS "${synclib_NAME}_vfs_suffix"
- LIBRARY DESTINATION "${vfs_installdir}"
- RUNTIME DESTINATION "${vfs_installdir}"
-)
-
}
} // namespace OCC
+
+OCC_DEFINE_VFS_FACTORY("suffix", OCC::VfsSuffix)
#include <QScopedPointer>
#include "common/vfs.h"
-#include "common/plugin.h"
namespace OCC {
void startImpl(const VfsSetupParams ¶ms) override;
};
-class SuffixVfsPluginFactory : public QObject, public DefaultPluginFactory<VfsSuffix>
-{
- Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.owncloud.PluginFactory" FILE "vfspluginmetadata.json")
- Q_INTERFACES(OCC::PluginFactory)
-};
-
} // namespace OCC