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