6 #include "application.h" 9 #include "controller.h" 10 #include "controller_p.h" 11 #include "dispatcher_p.h" 12 #include "dispatchtypechained.h" 13 #include "dispatchtypepath.h" 15 #include "request_p.h" 18 #include <QMetaMethod> 26 , d_ptr(new DispatcherPrivate(this))
47 bool instanceUsed =
false;
49 for (
Action *action : actions) {
50 bool registered =
false;
51 if (!d->actions.contains(action->reverse())) {
52 if (!action->attributes().contains(QStringLiteral(
"Private"))) {
55 if (
dispatch->registerAction(action)) {
70 d->actions.insert(name, {name, action});
71 auto it = d->actionContainer.find(action->ns());
72 if (it != d->actionContainer.end()) {
73 it->actions << action;
75 d->actionContainer.insert(action->ns(), {action->ns(), {action}});
78 registeredActions.
append(action);
81 qCDebug(CUTELYST_DISPATCHER)
82 <<
"The action" << action->name() <<
"of" << action->controller()->objectName()
83 <<
"controller was not registered in any dispatcher." 84 " If you still want to access it internally (via actionFor())" 85 " you may make it's method private.";
99 d->rootActions = d->actionContainer.value(u
"").actions;
109 if (!type->
inUse()) {
110 d->dispatchers.removeAt(i);
119 qCDebug(CUTELYST_DISPATCHER) <<
dispatch->list().constData();
154 Action *action = d->command2Action(c, opname, c->
request()->args());
159 qCCritical(CUTELYST_DISPATCHER) <<
"Action not found" << opname << c->
request()->args();
168 d->prepareAction(c, request->path());
170 static const bool log = CUTELYST_DISPATCHER().isDebugEnabled();
172 if (!request->match().
isEmpty()) {
173 qCDebug(CUTELYST_DISPATCHER) <<
"Path is" << request->match();
176 if (!request->args().
isEmpty()) {
177 qCDebug(CUTELYST_DISPATCHER) <<
"Arguments are" << request->args().
join(u
'/');
195 if (type->match(c, path, args) == DispatchType::ExactMatch) {
226 const QString normName = u
'/' + name;
227 return d->actions.value(normName).action;
237 int slashes = path.
count(u
'/');
239 return d->actions.value(
QString{u
'/' + path}).action;
240 }
else if (path.
startsWith(u
'/') && slashes != 1) {
241 return d->actions.value(path.
mid(1)).action;
243 return d->actions.value(path).action;
256 const ActionList containers = d->getContainers(nameSpace);
257 auto rIt = containers.
rbegin();
258 while (rIt != containers.
rend()) {
259 if ((*rIt)->name() == name) {
270 return d->controllers.value(name).controller;
277 for (
const auto &value : d->controllers) {
278 ret.
append(value.controller);
287 if (Q_UNLIKELY(action ==
nullptr)) {
288 qCCritical(CUTELYST_DISPATCHER) <<
"Dispatcher::uriForAction called with null action";
292 ret =
dispatch->uriForAction(action, captures);
309 if (expandedAction) {
310 return expandedAction;
319 return d->dispatchers;
322 void DispatcherPrivate::printActions()
const 326 auto keys = actions.keys();
327 std::sort(keys.begin(), keys.end());
328 for (
const auto &key : keys) {
329 Action *action = actions.value(key).action;
342 qCDebug(CUTELYST_DISPATCHER) << Utils::buildTable(table,
359 ret.
append(actionContainer.value(ns.
mid(0, pos)).actions);
373 auto it = actions.constFind(command);
374 if (it != actions.constEnd()) {
375 return it.value().action;
378 return invokeAsPath(c, command, args);
389 const QString path = DispatcherPrivate::actionRel2Abs(c, relativePath);
393 int lastPos = pathView.size();
396 ret = q->getAction(pathView);
401 const auto name = pathView.mid(pos + 1, lastPos);
402 pathView = pathView.mid(0, pos);
403 ret = q->getAction(name, pathView);
410 pos = pathView.indexOf(u
'/', pos - 1);
433 #include "moc_dispatcher.cpp" Controller * controller() const noexcept
bool dispatch(Context *c)
qsizetype count(QChar ch, Qt::CaseSensitivity cs) const const
QString uriForAction(Action *action, const QStringList &captures) const
bool dispatch(Context *c)
void setupActions(const QVector< Controller *> &controllers, const QVector< DispatchType *> &dispatchers, bool printActions)
bool isEmpty() const const
void truncate(qsizetype length)
Action * getAction(QStringView name, QStringView nameSpace={}) const
QString & prepend(QChar ch)
qsizetype size() const const
Controller * controller(QStringView name) const
QStringView mid(qsizetype start, qsizetype length) const const
bool forward(Context *c, Component *component)
Action * getActionByPath(QStringView path) const
QString join(QChar separator) const const
void prepareAction(Context *c)
reverse_iterator rbegin()
void appendError(const QString &error)
QVector< DispatchType * > dispatchers() const
The Cutelyst Component base class.
qsizetype lastIndexOf(QChar ch, Qt::CaseSensitivity cs) const const
bool startsWith(QChar ch) const const
bool isNull() const const
This class represents a Cutelyst Action.
Cutelyst Controller base class.
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
bool isEmpty() const const
QList< Controller * > controllers() const
QString name() const noexcept
bool _DISPATCH(Context *c)
The Cutelyst namespace holds all public Cutelyst API.
bool execute(Component *code)
qsizetype length() const const
qsizetype lastIndexOf(QChar c, Qt::CaseSensitivity cs) const const
Describes a path dispatch type.
ActionList getActions(QStringView name, QStringView nameSpace) const
int compare(QChar ch) const const
QStack< Component * > stack() const noexcept
Action * expandAction(const Context *c, Action *action) const
QString qtTrId(const char *id, int n=-1) const
QString toString() const const
Describes a chained dispatch type.
void append(QList< T > &&value)
Abstract class to described a dispatch type.
QObject * parent() const const
Dispatcher(QObject *parent=nullptr)
QString arg(Args &&... args) const const
ActionList actions() const noexcept
QString className() const noexcept