Skip to content

Commit

Permalink
Refactor: Using priv idiom in ClassHandlerManager to ease the
Browse files Browse the repository at this point in the history
responsibility of maintain ABI compability in future versions.
  • Loading branch information
vinipsmaker committed Feb 25, 2014
1 parent 3be4bcd commit 7a10ba6
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 23 deletions.
39 changes: 23 additions & 16 deletions src/classhandlermanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
You should have received a copy of the GNU Lesser General Public License
along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "classhandlermanager.h"
#include "priv/classhandlermanager.h"

#include "classhandler.h"

Expand Down Expand Up @@ -48,10 +48,11 @@ QStringList ClassHandlerManager::pluginLocations;
/* ************************************************************************** */
/* Object lifecycle */
/* ************************************************************************** */
ClassHandlerManager::ClassHandlerManager(QString pluginID, QString context, QObject * parent) :
ClassHandlerManager::ClassHandlerManager(const QString &pluginID,
const QString &context,
QObject * parent) :
QObject(parent),
pluginID(pluginID),
m_context(context)
priv{new Priv{pluginID, context}}
{
// Set up the search locations
if(pluginLocations.isEmpty()) {
Expand Down Expand Up @@ -152,17 +153,18 @@ ClassHandlerManager::ClassHandlerManager(QString pluginID, QString context, QObj

ClassHandlerManager::~ClassHandlerManager()
{
foreach (ClassHandlerManager::PluginDescriptor * descriptor, handlers) {
foreach (ClassHandlerManager::PluginDescriptor *descriptor, priv->handlers) {
delete descriptor;
}
delete priv;
}

/* ************************************************************************** */
/* Accessors & mutators */
/* ************************************************************************** */
QString ClassHandlerManager::context(void) const
{
return m_context;
return priv->context;
}

/* ************************************************************************** */
Expand Down Expand Up @@ -245,7 +247,8 @@ bool ClassHandlerManager::processRequest(HttpServerRequest & request,
bool canHandle = true;
int methodIndex = selectMethod(className, methodName, arguments);
if(methodIndex > -1) {
ClassHandlerManager::PluginDescriptor * handler = handlers[className];
ClassHandlerManager::PluginDescriptor *handler
= priv->handlers[className];
QMetaMethod method = handler->handler->metaObject()->method(methodIndex);

// Create the arguments
Expand Down Expand Up @@ -297,7 +300,7 @@ bool ClassHandlerManager::processRequest(HttpServerRequest & request,
void ClassHandlerManager::registerHandler(ClassHandler * handler)
{
// Only process plugins that have not already been registered.
if (!handlers.contains(handler->objectName())){
if (!priv->handlers.contains(handler->objectName())){
qDebug() << "Registering " << handler->objectName() << " as a handler.";
bool canDispathTo = false;
const QMetaObject* metaObject = handler->metaObject();
Expand All @@ -308,10 +311,12 @@ void ClassHandlerManager::registerHandler(ClassHandler * handler)
QList<QByteArray> parameterNames = method.parameterNames();
if(parameterNames[0] == QByteArray("request") && parameterNames[1] == QByteArray("response")) {
canDispathTo = true;
ClassHandlerManager::PluginDescriptor * pluginDescriptor = handlers[handler->objectName()];
ClassHandlerManager::PluginDescriptor *pluginDescriptor
= priv->handlers[handler->objectName()];
if(pluginDescriptor == NULL) {
pluginDescriptor = new ClassHandlerManager::PluginDescriptor();
handlers[handler->objectName()] = pluginDescriptor;
priv->handlers[handler->objectName()]
= pluginDescriptor;
}
pluginDescriptor->className = handler->objectName();
pluginDescriptor->handler = handler;
Expand Down Expand Up @@ -346,7 +351,7 @@ int ClassHandlerManager::selectMethod(const QString className,
foreach (QString key, arguments.keys()) {
parameterHash += qHash(key);
}
PluginDescriptor * pluginDescriptor = handlers[className];
PluginDescriptor *pluginDescriptor = priv->handlers[className];
if (pluginDescriptor->methods.contains(parameterHash)) {
methodIndex = pluginDescriptor->methods.value(parameterHash);
}
Expand All @@ -363,7 +368,7 @@ bool ClassHandlerManager::handleRequest(Tufao::HttpServerRequest & request, Tufa


//Is the request for our context?
bool useContext = !m_context.isEmpty();
bool useContext = !priv->context.isEmpty();
// There must be at least two path components (class & method), and 3 if a context is specified.
int minimumPathComponents = useContext ? 3 : 2;
if (pathComponents.length() < minimumPathComponents) {
Expand All @@ -374,17 +379,19 @@ bool ClassHandlerManager::handleRequest(Tufao::HttpServerRequest & request, Tufa
qWarning() << "Request was dispatched to handler, but too many path components found. The path components are"
<< pathComponents;
} else {
if(!useContext || m_context == pathComponents[0]) {
if(!useContext || priv->context == pathComponents[0]) {
// Add the context to the request
request.setContext(m_context);
request.setContext(priv->context);

int pathIndex = useContext ? 1 : 0;
QString className = pathComponents[pathIndex++];
QString methodName = pathComponents[pathIndex++];
// We need to have an even number of path components left
if((pathComponents.length() - pathIndex) % 2 == 0) {
// See if we have a class handler with a matching method
if(handlers.contains(className) && handlers[className]->methodNames.contains(methodName)) {
if (priv->handlers.contains(className)
&& (priv->handlers[className]->methodNames
.contains(methodName))) {
// Convert the remaining path components into an argument hash
QHash<QString, QString> arguments;
while(pathIndex < pathComponents.length()){
Expand All @@ -393,7 +400,7 @@ bool ClassHandlerManager::handleRequest(Tufao::HttpServerRequest & request, Tufa
}
wasHandled = processRequest(request, response, className, methodName, arguments);
} else {
if(handlers.contains(className)) {
if (priv->handlers.contains(className)) {
qWarning() << "The class" << className << "has no method named" << methodName;
}
}
Expand Down
12 changes: 5 additions & 7 deletions src/classhandlermanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ class ClassHandlerManager : public QObject, public AbstractHttpServerRequestHand
* the request get dispatched.
* \param parent is passed to the QObject constructor.
*/
explicit ClassHandlerManager(QString pluginID = "", QString context="", QObject * parent = 0);
explicit ClassHandlerManager(const QString &pluginID = QString{},
const QString &context = QString{},
QObject * parent = 0);

/*!
Destroys the object.
Expand Down Expand Up @@ -133,15 +135,11 @@ public slots:

int selectMethod(const QString className, const QString methodName, const QHash<QString, QString> arguments) const;

//! Maps a class name or pluginID to the PluginDescriptor for the plugin.
QHash<QString, ClassHandlerManager::PluginDescriptor *> handlers;
//! The IID of the plugins this manager will load. May be empty.
QString pluginID;
//! The paths dearched to find plugins.
static QStringList pluginLocations;

//! The contect - first path component of the URI - this manager is responsible for. May be empty.
QString m_context;
struct Priv;
Priv *priv;
};

} // namespace Tufao
Expand Down
43 changes: 43 additions & 0 deletions src/priv/classhandlermanager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/* This file is part of the Tufão project
Copyright (C) 2013 Timothy Reaves [email protected]
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, see <http://www.gnu.org/licenses/>.
*/

#ifndef TUFAO_PRIV_CLASSHANDLERMANAGER_H
#define TUFAO_PRIV_CLASSHANDLERMANAGER_H

#include "../classhandlermanager.h"

namespace Tufao {

struct ClassHandlerManager::Priv
{
Priv(const QString &pluginID, const QString &context) :
pluginID(pluginID),
context(context)
{}

//! Maps a class name or pluginID to the PluginDescriptor for the plugin.
QHash<QString, ClassHandlerManager::PluginDescriptor *> handlers;
//! The IID of the plugins this manager will load. May be empty.
QString pluginID;
//! The contect - first path component of the URI - this manager is responsible for. May be empty.
QString context;
};

} // namespace Tufao

#endif // TUFAO_PRIV_CLASSHANDLERMANAGER_H

0 comments on commit 7a10ba6

Please sign in to comment.