summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/Disco/FeatureOracle.cpp')
-rw-r--r--Swiften/Disco/FeatureOracle.cpp99
1 files changed, 99 insertions, 0 deletions
diff --git a/Swiften/Disco/FeatureOracle.cpp b/Swiften/Disco/FeatureOracle.cpp
new file mode 100644
index 0000000..4e61aa9
--- /dev/null
+++ b/Swiften/Disco/FeatureOracle.cpp
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2015 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swiften/Disco/FeatureOracle.h>
+
+#include <algorithm>
+#include <iterator>
+#include <vector>
+
+#include <Swiften/Base/foreach.h>
+#include <Swiften/Disco/EntityCapsProvider.h>
+#include <Swiften/Elements/Presence.h>
+#include <Swiften/FileTransfer/FileTransferManager.h>
+#include <Swiften/JID/JID.h>
+#include <Swiften/Presence/PresenceOracle.h>
+
+namespace Swift {
+
+FeatureOracle::FeatureOracle(EntityCapsProvider* capsProvider, PresenceOracle* presenceOracle) : capsProvider_(capsProvider), presenceOracle_(presenceOracle) {
+
+}
+
+Tristate FeatureOracle::isFileTransferSupported(const JID& jid) {
+ DiscoInfo::ref discoInfo = getDiscoResultForJID(jid);
+ if (discoInfo) {
+ return FileTransferManager::isSupportedBy(discoInfo) ? Yes : No;
+ }
+ else {
+ return Maybe;
+ }
+}
+
+Tristate FeatureOracle::isMessageReceiptsSupported(const JID& jid) {
+ return isFeatureSupported(jid, DiscoInfo::MessageDeliveryReceiptsFeature);
+}
+
+Tristate FeatureOracle::isMessageCorrectionSupported(const JID& jid) {
+ return isFeatureSupported(jid, DiscoInfo::MessageCorrectionFeature);
+}
+
+DiscoInfo::ref FeatureOracle::getDiscoResultForJID(const JID& jid) {
+ DiscoInfo::ref discoInfo;
+ if (jid.isBare()) {
+ // Calculate the common subset of disco features of all available results and return that.
+ std::vector<Presence::ref> availablePresences = presenceOracle_->getAllPresence(jid);
+
+ bool commonFeaturesInitialized = false;
+ std::vector<std::string> commonFeatures;
+ foreach(Presence::ref presence, availablePresences) {
+ DiscoInfo::ref presenceDiscoInfo = capsProvider_->getCaps(presence->getFrom());
+ if (presenceDiscoInfo) {
+ std::vector<std::string> features = presenceDiscoInfo->getFeatures();
+ if (!commonFeaturesInitialized) {
+ commonFeatures = features;
+ commonFeaturesInitialized = true;
+ }
+ else {
+ std::vector<std::string> featuresToRemove;
+ foreach(const std::string& feature, commonFeatures) {
+ if (std::find(features.begin(), features.end(), feature) == features.end()) {
+ featuresToRemove.push_back(feature);
+ }
+ }
+ foreach(const std::string& featureToRemove, featuresToRemove) {
+ commonFeatures.erase(std::remove(commonFeatures.begin(), commonFeatures.end(), featureToRemove), commonFeatures.end());
+ }
+ }
+ }
+ }
+ discoInfo = boost::make_shared<DiscoInfo>();
+
+ foreach(const std::string& commonFeature, commonFeatures) {
+ discoInfo->addFeature(commonFeature);
+ }
+ }
+ else {
+ // Return the disco result of the full JID.
+ discoInfo = capsProvider_->getCaps(jid);
+ }
+
+ return discoInfo;
+}
+
+Tristate FeatureOracle::isFeatureSupported(const JID& jid, const std::string& feature) {
+ DiscoInfo::ref discoInfo = getDiscoResultForJID(jid);
+ if (discoInfo) {
+ return discoInfo->hasFeature(feature) ? Yes : No;
+ }
+ else {
+ return Maybe;
+ }
+}
+
+}
+
+