18 #include "context_p.h"
24 #include "dispatcher.h"
25 #include "controller.h"
26 #include "application.h"
34 #include <QCoreApplication>
44 d_ptr(new ContextPrivate(app, app->engine(), app->dispatcher(), app->plugins()))
46 auto req =
new DummyRequest(
this);
52 d_ptr->request =
new Request(req);
53 d_ptr->request->d_ptr->engine = d_ptr->engine;
58 delete d_ptr->request;
59 delete d_ptr->response;
66 return !d->error.isEmpty();
72 if (
error.isEmpty()) {
76 qCCritical(CUTELYST_CORE) <<
error;
86 bool Context::state()
const
131 return d->action->name();
137 return d->action->ns();
155 return d->dispatcher;
158 QString Cutelyst::Context::controllerName()
const
167 return d->action->controller();
173 return d->dispatcher->controllers().value(name);
185 return d->app->view(name);
191 d->view = d->app->view(name);
204 return d->stash.value(key);
210 return d->stash.value(key, defaultValue);
216 return d->stash.take(key);
222 return d->stash.remove(key);
228 d->stash.insert(key, value);
247 QUrl uri = d->request->uri();
252 const QString controllerNS = d->action->controller()->ns();
276 if (queryValues.
size()) {
294 Action *localAction = action;
296 localAction = d->action;
302 Action *expandedAction = d->dispatcher->expandAction(
this, action);
305 && localArgs.
size()) {
310 localCapturesAux.
append(localArgs);
311 localArgs = localCapturesAux;
315 const QString path = d->dispatcher->uriForAction(localAction, localCaptures);
317 qCWarning(CUTELYST_CORE) <<
"Can not find action for" << localAction << localCaptures;
321 uri =
uriFor(path, localArgs, queryValues);
330 Action *action = d->dispatcher->getActionByPath(path);
332 qCWarning(CUTELYST_CORE) <<
"Can not find action for" << path;
336 uri =
uriFor(action, captures, args, queryValues);
350 d->dispatcher->forward(
this, action);
365 if (--d->asyncDetached) {
369 if (Q_UNLIKELY(d->engineRequest->status & EngineRequest::Finalized)) {
370 qCWarning(CUTELYST_ASYNC) <<
"Trying to async attach to a finalized request! Skipping...";
374 if (d->engineRequest->status & EngineRequest::Async) {
375 while (d->asyncAction < d->pendingAsync.size()) {
376 Action *action = d->pendingAsync[d->asyncAction++];
379 }
else if (d->asyncDetached) {
384 Q_EMIT d->app->afterDispatch(
this);
393 return d->dispatcher->forward(
this, action);
399 return d->dispatcher->forward(
this, action);
405 return d->dispatcher->getAction(action, ns);
411 return d->dispatcher->getActions(action, ns);
423 Q_ASSERT_X(code,
"Context::execute",
"trying to execute a null Cutelyst::Component");
425 static int recursion = qEnvironmentVariableIsSet(
"RECURSION") ? qEnvironmentVariableIntValue(
"RECURSION") : 1000;
426 if (d->stack.size() >= recursion) {
427 QString msg = QStringLiteral(
"Deep recursion detected (stack size %1) calling %2, %3")
438 const QString statsInfo = d->statsStartExecute(code);
444 if (d->stats && !statsInfo.
isEmpty()) {
445 d->statsFinishExecute(statsInfo);
471 return d->app->config(key, defaultValue);
474 QVariantMap Context::config()
const
477 return d->app->config();
483 return d->app->translate(d->locale, context, sourceText, disambiguation, n);
490 if (Q_UNLIKELY(d->engineRequest->status & EngineRequest::Finalized)) {
491 qCWarning(CUTELYST_CORE) <<
"Trying to finalize a finalized request! Skipping...";
496 qCDebug(CUTELYST_STATS,
"Response Code: %d; Content-Type: %s; Content-Length: %s",
497 d->response->status(),
498 qPrintable(d->response->headers().header(QStringLiteral(
"CONTENT_TYPE"), QStringLiteral(
"unknown"))),
499 qPrintable(d->response->headers().header(QStringLiteral(
"CONTENT_LENGTH"), QStringLiteral(
"unknown"))));
501 const double enlapsed = d->engineRequest->elapsed.nsecsElapsed() / 1000000000.0;
503 if (enlapsed == 0.0) {
504 average = QStringLiteral(
"??");
509 qCInfo(CUTELYST_STATS) << qPrintable(QStringLiteral(
"Request took: %1s (%2/s)\n%3")
517 d->engineRequest->finalize();
530 if (qobject_cast<Action *>(code)) {
534 if (stack.size() > 2) {
539 stats->profileStart(actionName);
544 void ContextPrivate::statsFinishExecute(
const QString &statsInfo)
546 stats->profileEnd(statsInfo);
552 auto it = unite.constBegin();
553 while (it != unite.constEnd()) {
554 d->stash.insert(it.key(), it.value());
559 #include "moc_context.cpp"
560 #include "moc_context_p.cpp"
This class represents a Cutelyst Action.
virtual qint8 numberOfCaptures() const
The Cutelyst Application.
Headers & defaultHeaders()
The Cutelyst Component base class.
void setState(bool state)
Sets the state of the current executed action, setting to false will make the dispatcher skip non pro...
bool forward(Component *component)
QUrl uriFor(const QString &path=QString(), const QStringList &args=QStringList(), const ParamsMultiMap &queryValues=ParamsMultiMap()) const
Dispatcher * dispatcher() const
QVector< Plugin * > plugins() const
Context(Application *app)
Constructs a new DUMMY Context object that is child of Application This currently is experimental to ...
bool error() const
Returns true if an error was set.
Application * app() const
void detach(Action *action=nullptr)
QStringList errors() const
Returns a list of errors that were defined.
QVector< Action * > getActions(const QString &action, const QString &ns=QString()) const
QStack< Component * > stack() const
QString translate(const char *context, const char *sourceText, const char *disambiguation=nullptr, int n=-1) const
void setStash(const QString &key, const QVariant &value)
View * customView() const
void finalize()
finalize the request right away this is automatically called at the end of the actions chain
bool stashRemove(const QString &key)
QVariant stashTake(const QString &key)
void attachAsync()
attachAsync
void setLocale(const QLocale &locale)
Response * response() const
QUrl uriForAction(const QString &path, const QStringList &captures=QStringList(), const QStringList &args=QStringList(), const ParamsMultiMap &queryValues=ParamsMultiMap()) const
bool execute(Component *code)
bool setCustomView(const QString &name)
View * view(const QString &name=QString()) const
Action * getAction(const QString &action, const QString &ns=QString()) const
Cutelyst Controller base class
Cutelyst View abstract view component
The Cutelyst namespace holds all public Cutelyst API.
virtual bool open(QIODevice::OpenMode mode)
void append(const T &value)
bool isEmpty() const const
QMap::const_iterator constBegin() const const
QMap::const_iterator constEnd() const const
bool isEmpty() const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
QString fromLatin1(const char *str, int size)
bool isEmpty() const const
QString number(int n, int base)
QString & prepend(QChar ch)
QString rightJustified(int width, QChar fill, bool truncate) const const
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
void truncate(int position)
QString join(const QString &separator) const const
void setPath(const QString &path, QUrl::ParsingMode mode)
void setQuery(const QString &query, QUrl::ParsingMode mode)
void addQueryItem(const QString &key, const QString &value)
QVariant fromValue(const T &value)