Cutelyst  2.13.0
action.cpp
1 /*
2  * Copyright (C) 2013-2017 Daniel Nicoletti <dantti12@gmail.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 #include "action_p.h"
19 #include "controller.h"
20 #include "context.h"
21 #include "common.h"
22 
23 using namespace Cutelyst;
24 
25 Action::Action(QObject *parent) : Component(new ActionPrivate, parent)
26 {
27 }
28 
29 Action::Action(ActionPrivate *ptr, QObject *parent) : Component(ptr, parent)
30 {
31 }
32 
33 Component::Modifiers Action::modifiers() const
34 {
35  return Component::OnlyExecute;
36 }
37 
38 void Action::setMethod(const QMetaMethod &method)
39 {
40  Q_D(Action);
41  d->method = method;
42  if (method.returnType() == QMetaType::Bool) {
43  d->evaluateBool = true;
44  }
45 
46  if (method.parameterCount() == 2 && method.parameterType(1) == QMetaType::QStringList) {
47  d->listSignature = true;
48  }
49 }
50 
52 {
53  Q_D(Action);
54  d->controller = controller;
55 }
56 
57 void Action::setupAction(const QVariantHash &args, Application *app)
58 {
59  Q_D(Action);
60 
61  init(app, args);
62 
63  d->ns = args.value(QLatin1String("namespace")).toString();
64 
65  const auto attributes = args.value(QLatin1String("attributes")).value<QMap<QString, QString> >();
66  d->attributes = attributes;
67 
68  const QString argsAttr = attributes.value(QLatin1String("Args"));
69  if (!argsAttr.isEmpty()) {
70  d->numberOfArgs = qint8(argsAttr.toInt());
71  }
72 
73  const QString capturesAttr = attributes.value(QLatin1String("CaptureArgs"));
74  if (!capturesAttr.isEmpty()) {
75  d->numberOfCaptures = qint8(capturesAttr.toInt());
76  }
77 }
78 
79 QMap<QString, QString> Action::attributes() const
80 {
81  Q_D(const Action);
82  return d->attributes;
83 }
84 
85 QString Action::attribute(const QString &name, const QString &defaultValue) const
86 {
87  Q_D(const Action);
88  return d->attributes.value(name, defaultValue);
89 }
90 
91 void Action::setAttributes(const QMap<QString, QString> &attributes)
92 {
93  Q_D(Action);
94  d->attributes = attributes;
95 }
96 
97 QString Action::className() const
98 {
99  Q_D(const Action);
100  return QString::fromLatin1(d->controller->metaObject()->className());
101 }
102 
104 {
105  Q_D(const Action);
106  return d->controller;
107 }
108 
109 bool Action::match(int numberOfArgs) const
110 {
111  Q_D(const Action);
112  // If the number of args is -1 (not defined)
113  // it will slurp all args so we don't care
114  // about how many args was passed, otherwise
115  // count them
116  return d->numberOfArgs == -1 || d->numberOfArgs == numberOfArgs;
117 }
118 
119 bool Action::matchCaptures(int numberOfCaptures) const
120 {
121  Q_D(const Action);
122  // If the number of capture args is -1 (not defined)
123  // it will slurp all args so we don't care
124  // about how many args was passed, otherwise
125  // count them
126  return d->numberOfCaptures == -1 || d->numberOfCaptures == numberOfCaptures;
127 }
128 
129 QString Action::ns() const
130 {
131  Q_D(const Action);
132  return d->ns;
133 }
134 
135 qint8 Action::numberOfArgs() const
136 {
137  Q_D(const Action);
138  return d->numberOfArgs;
139 }
140 
142 {
143  Q_D(const Action);
144  return d->numberOfCaptures;
145 }
146 
148 {
149  Q_D(const Action);
150  if (c->detached()) {
151  return false;
152  }
153 
154  bool ret;
155  if (d->evaluateBool) {
156  bool methodRet;
157 
158  if (d->listSignature) {
159  ret = d->method.invoke(d->controller,
160  Qt::DirectConnection,
161  Q_RETURN_ARG(bool, methodRet),
162  Q_ARG(Cutelyst::Context*, c),
163  Q_ARG(QStringList, c->request()->args()));
164  } else {
165  QStringList args = c->request()->args();
166  // Fill the missing arguments
167  args.append(d->emptyArgs);
168 
169  ret = d->method.invoke(d->controller,
170  Qt::DirectConnection,
171  Q_RETURN_ARG(bool, methodRet),
172  Q_ARG(Cutelyst::Context*, c),
173  Q_ARG(QString, args.at(0)),
174  Q_ARG(QString, args.at(1)),
175  Q_ARG(QString, args.at(2)),
176  Q_ARG(QString, args.at(3)),
177  Q_ARG(QString, args.at(4)),
178  Q_ARG(QString, args.at(5)),
179  Q_ARG(QString, args.at(6)),
180  Q_ARG(QString, args.at(7)),
181  Q_ARG(QString, args.at(8)));
182  }
183 
184  if (ret) {
185  c->setState(methodRet);
186  return methodRet;
187  }
188 
189  // The method failed to be called which means we should detach
190  c->detach();
191  c->setState(false);
192 
193  return false;
194  } else {
195  if (d->listSignature) {
196  ret = d->method.invoke(d->controller,
197  Qt::DirectConnection,
198  Q_ARG(Cutelyst::Context*, c),
199  Q_ARG(QStringList, c->request()->args()));
200  } else {
201  QStringList args = c->request()->args();
202  // Fill the missing arguments
203  args.append(d->emptyArgs);
204 
205  ret = d->method.invoke(d->controller,
206  Qt::DirectConnection,
207  Q_ARG(Cutelyst::Context*, c),
208  Q_ARG(QString, args.at(0)),
209  Q_ARG(QString, args.at(1)),
210  Q_ARG(QString, args.at(2)),
211  Q_ARG(QString, args.at(3)),
212  Q_ARG(QString, args.at(4)),
213  Q_ARG(QString, args.at(5)),
214  Q_ARG(QString, args.at(6)),
215  Q_ARG(QString, args.at(7)),
216  Q_ARG(QString, args.at(8)));
217  }
218  c->setState(ret);
219  return ret;
220  }
221 }
222 
223 #include "moc_action.cpp"
Cutelyst::Controller
Cutelyst Controller base class
Definition: controller.h:102
Cutelyst::Action::setupAction
void setupAction(const QVariantHash &args, Application *app)
Definition: action.cpp:57
Cutelyst::Context::detach
void detach(Action *action=nullptr)
Definition: context.cpp:346
Cutelyst::Action::setMethod
void setMethod(const QMetaMethod &method)
Definition: action.cpp:38
Cutelyst::Application
The Cutelyst Application.
Definition: application.h:55
Cutelyst::Context
The Cutelyst Context.
Definition: context.h:50
Cutelyst::Component::init
virtual bool init(Application *application, const QVariantHash &args)
Definition: component.cpp:68
Cutelyst::Component
The Cutelyst Component base class.
Definition: component.h:38
Cutelyst::Action::numberOfArgs
virtual qint8 numberOfArgs() const
Definition: action.cpp:135
Cutelyst::Action::attributes
QMap< QString, QString > attributes() const
Definition: action.cpp:79
Cutelyst::Action::modifiers
virtual Modifiers modifiers() const override
Definition: action.cpp:33
Cutelyst::Action::attribute
QString attribute(const QString &name, const QString &defaultValue=QString()) const
Definition: action.cpp:85
Cutelyst
The Cutelyst namespace holds all public Cutelyst API.
Definition: Mainpage.dox:7
Cutelyst::Component::name
QString name() const
Definition: component.cpp:44
Cutelyst::Action::doExecute
virtual bool doExecute(Context *c) override
Definition: action.cpp:147
Cutelyst::Action
This class represents a Cutelyst Action.
Definition: action.h:47
Cutelyst::Action::matchCaptures
virtual bool matchCaptures(int numberOfCaptures) const
Definition: action.cpp:119
Cutelyst::Action::setController
void setController(Controller *controller)
Definition: action.cpp:51
Cutelyst::Action::ns
QString ns() const
Definition: action.cpp:129
Cutelyst::Action::Action
Action(QObject *parent=nullptr)
Definition: action.cpp:25
Cutelyst::Action::className
QString className() const
Definition: action.cpp:97
Cutelyst::Action::numberOfCaptures
virtual qint8 numberOfCaptures() const
Definition: action.cpp:141
Cutelyst::Action::match
virtual bool match(int numberOfArgs) const
Definition: action.cpp:109
Cutelyst::Action::setAttributes
void setAttributes(const QMap< QString, QString > &attributes)
Definition: action.cpp:91
Cutelyst::Context::setState
void setState(bool state)
Sets the state of the current executed action, setting to false will make the dispatcher skip non pro...
Definition: context.cpp:92
Cutelyst::Action::controller
Controller * controller() const
Definition: action.cpp:103
Cutelyst::Context::detached
bool detached() const
Definition: context.cpp:340