cutelyst  3.7.0
A C++ Web Framework built on top of Qt, using the simple approach of Catalyst (Perl) framework.
action.cpp
1 /*
2  * SPDX-FileCopyrightText: (C) 2013-2022 Daniel Nicoletti <dantti12@gmail.com>
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 #include "action_p.h"
6 #include "controller.h"
7 #include "context.h"
8 #include "common.h"
9 
10 using namespace Cutelyst;
11 
12 Action::Action(QObject *parent) : Component(new ActionPrivate, parent)
13 {
14 }
15 
16 Action::Action(ActionPrivate *ptr, QObject *parent) : Component(ptr, parent)
17 {
18 }
19 
20 Component::Modifiers Action::modifiers() const
21 {
22  return Component::OnlyExecute;
23 }
24 
25 void Action::setMethod(const QMetaMethod &method)
26 {
27  Q_D(Action);
28  d->method = method;
29  if (method.returnType() == QMetaType::Bool) {
30  d->evaluateBool = true;
31  }
32 
33  if (method.parameterCount() == 2 && method.parameterType(1) == QMetaType::QStringList) {
34  d->listSignature = true;
35  }
36 }
37 
39 {
40  Q_D(Action);
41  d->controller = controller;
42 }
43 
44 void Action::setupAction(const QVariantHash &args, Application *app)
45 {
46  Q_D(Action);
47 
48  init(app, args);
49 
50  d->ns = args.value(QLatin1String("namespace")).toString();
51 
52  const auto attributes = args.value(QLatin1String("attributes")).value<ParamsMultiMap>();
53  d->attributes = attributes;
54 
55  const QString argsAttr = attributes.value(QLatin1String("Args"));
56  if (!argsAttr.isEmpty()) {
57  d->numberOfArgs = qint8(argsAttr.toInt());
58  }
59 
60  const QString capturesAttr = attributes.value(QLatin1String("CaptureArgs"));
61  if (!capturesAttr.isEmpty()) {
62  d->numberOfCaptures = qint8(capturesAttr.toInt());
63  }
64 }
65 
67 {
68  Q_D(const Action);
69  return d->attributes;
70 }
71 
72 QString Action::attribute(const QString &name, const QString &defaultValue) const
73 {
74  Q_D(const Action);
75  return d->attributes.value(name, defaultValue);
76 }
77 
78 void Action::setAttributes(const ParamsMultiMap &attributes)
79 {
80  Q_D(Action);
81  d->attributes = attributes;
82 }
83 
84 QString Action::className() const
85 {
86  Q_D(const Action);
87  return QString::fromLatin1(d->controller->metaObject()->className());
88 }
89 
91 {
92  Q_D(const Action);
93  return d->controller;
94 }
95 
96 bool Action::match(int numberOfArgs) const noexcept
97 {
98  Q_D(const Action);
99  // If the number of args is -1 (not defined)
100  // it will slurp all args so we don't care
101  // about how many args was passed, otherwise
102  // count them
103  return d->numberOfArgs == -1 || d->numberOfArgs == numberOfArgs;
104 }
105 
106 bool Action::matchCaptures(int numberOfCaptures) const noexcept
107 {
108  Q_D(const Action);
109  // If the number of capture args is -1 (not defined)
110  // it will slurp all args so we don't care
111  // about how many args was passed, otherwise
112  // count them
113  return d->numberOfCaptures == -1 || d->numberOfCaptures == numberOfCaptures;
114 }
115 
116 QString Action::ns() const noexcept
117 {
118  Q_D(const Action);
119  return d->ns;
120 }
121 
122 qint8 Action::numberOfArgs() const noexcept
123 {
124  Q_D(const Action);
125  return d->numberOfArgs;
126 }
127 
128 qint8 Action::numberOfCaptures() const noexcept
129 {
130  Q_D(const Action);
131  return d->numberOfCaptures;
132 }
133 
135 {
136  Q_D(const Action);
137  if (c->detached()) {
138  return false;
139  }
140 
141  bool ret;
142  if (d->evaluateBool) {
143  bool methodRet;
144 
145  if (d->listSignature) {
146  ret = d->method.invoke(d->controller,
147  Qt::DirectConnection,
148  Q_RETURN_ARG(bool, methodRet),
149  Q_ARG(Cutelyst::Context*, c),
150  Q_ARG(QStringList, c->request()->args()));
151  } else {
152  QStringList args = c->request()->args();
153  // Fill the missing arguments
154  args.append(d->emptyArgs);
155 
156  ret = d->method.invoke(d->controller,
157  Qt::DirectConnection,
158  Q_RETURN_ARG(bool, methodRet),
159  Q_ARG(Cutelyst::Context*, c),
160  Q_ARG(QString, args.at(0)),
161  Q_ARG(QString, args.at(1)),
162  Q_ARG(QString, args.at(2)),
163  Q_ARG(QString, args.at(3)),
164  Q_ARG(QString, args.at(4)),
165  Q_ARG(QString, args.at(5)),
166  Q_ARG(QString, args.at(6)),
167  Q_ARG(QString, args.at(7)),
168  Q_ARG(QString, args.at(8)));
169  }
170 
171  if (ret) {
172  c->setState(methodRet);
173  return methodRet;
174  }
175 
176  // The method failed to be called which means we should detach
177  c->detach();
178  c->setState(false);
179 
180  return false;
181  } else {
182  if (d->listSignature) {
183  ret = d->method.invoke(d->controller,
184  Qt::DirectConnection,
185  Q_ARG(Cutelyst::Context*, c),
186  Q_ARG(QStringList, c->request()->args()));
187  } else {
188  QStringList args = c->request()->args();
189  // Fill the missing arguments
190  args.append(d->emptyArgs);
191 
192  ret = d->method.invoke(d->controller,
193  Qt::DirectConnection,
194  Q_ARG(Cutelyst::Context*, c),
195  Q_ARG(QString, args.at(0)),
196  Q_ARG(QString, args.at(1)),
197  Q_ARG(QString, args.at(2)),
198  Q_ARG(QString, args.at(3)),
199  Q_ARG(QString, args.at(4)),
200  Q_ARG(QString, args.at(5)),
201  Q_ARG(QString, args.at(6)),
202  Q_ARG(QString, args.at(7)),
203  Q_ARG(QString, args.at(8)));
204  }
205  c->setState(ret);
206  return ret;
207  }
208 }
209 
210 #include "moc_action.cpp"
This class represents a Cutelyst Action.
Definition: action.h:35
void setAttributes(const ParamsMultiMap &attributes)
Definition: action.cpp:78
void setupAction(const QVariantHash &args, Application *app)
Definition: action.cpp:44
virtual qint8 numberOfArgs() const noexcept
Definition: action.cpp:122
QString ns() const noexcept
Definition: action.cpp:116
virtual bool doExecute(Context *c) override
Definition: action.cpp:134
virtual qint8 numberOfCaptures() const noexcept
Definition: action.cpp:128
QString className() const
Definition: action.cpp:84
virtual bool match(int numberOfArgs) const noexcept
Definition: action.cpp:96
void setMethod(const QMetaMethod &method)
Definition: action.cpp:25
Action(QObject *parent=nullptr)
Definition: action.cpp:12
virtual Modifiers modifiers() const override
Definition: action.cpp:20
virtual bool matchCaptures(int numberOfCaptures) const noexcept
Definition: action.cpp:106
ParamsMultiMap attributes() const noexcept
Definition: action.cpp:66
void setController(Controller *controller)
Definition: action.cpp:38
Controller * controller() const
Definition: action.cpp:90
QString attribute(const QString &name, const QString &defaultValue={}) const
Definition: action.cpp:72
The Cutelyst Application.
Definition: application.h:43
The Cutelyst Component base class.
Definition: component.h:26
virtual bool init(Application *application, const QVariantHash &args)
Definition: component.cpp:55
QString name() const
Definition: component.cpp:31
The Cutelyst Context.
Definition: context.h:39
void detach(Action *action=nullptr)
Definition: context.cpp:339
void setState(bool state) noexcept
Sets the state of the current executed action, setting to false will make the dispatcher skip non pro...
Definition: context.cpp:79
bool detached() const noexcept
Definition: context.cpp:333
Cutelyst Controller base class
Definition: controller.h:90
The Cutelyst namespace holds all public Cutelyst API.
Definition: Mainpage.dox:8
QMultiMap< QString, QString > ParamsMultiMap