18 #include "controller_p.h" 20 #include "application.h" 21 #include "dispatcher.h" 25 #include "context_p.h" 27 #include <QMetaClassInfo> 28 #include <QRegularExpression> 33 , d_ptr(new ControllerPrivate(this))
37 Controller::~Controller()
40 qDeleteAll(d->actionList);
53 Action *ret = d->actions.value(name);
57 return d->dispatcher->getAction(name, d->pathPrefix);
68 return !qstrcmp(
metaObject()->className(), className);
83 ControllerPrivate::ControllerPrivate(
Controller *parent) :
92 dispatcher = _dispatcher;
100 q->setObjectName(className);
102 bool namespaceFound =
false;
109 namespaceFound =
true;
114 if (!namespaceFound) {
116 bool lastWasUpper =
true;
118 for (
int i = 0; i < className.
length(); ++i) {
119 const QChar c = className.
at(i);
122 lastWasUpper =
false;
134 pathPrefix = controlerNS;
137 registerActionMethods(meta, q, app);
140 void ControllerPrivate::setupFinished()
144 const ActionList beginList = dispatcher->getActions(QStringLiteral(
"Begin"), pathPrefix);
149 beginAutoList.append(dispatcher->getActions(QStringLiteral(
"Auto"), pathPrefix));
151 const ActionList endList = dispatcher->getActions(QStringLiteral(
"End"), pathPrefix);
153 end = endList.
last();
156 const auto actions = actionList;
157 for (
Action *action : actions) {
158 action->dispatcherReady(dispatcher, q);
161 q->preFork(qobject_cast<Application *>(q->parent()));
174 stack.
append(c->action());
176 auto rit = d->beginAutoList.crbegin();
177 while (rit != d->beginAutoList.crend()) {
181 c->d_ptr->pendingAsync = stack;
223 Action *ControllerPrivate::actionClass(
const QVariantHash &args)
226 const QString actionClass = attributes.value(QStringLiteral(
"ActionClass"));
228 QObject *
object = instantiateClass(actionClass,
"Cutelyst::Action");
234 qCWarning(CUTELYST_CONTROLLER) <<
"ActionClass" 236 <<
"is not an ActionClass";
245 Action *action = actionClass(args);
251 for (
int i = 0; i < roles.
size(); ++i) {
253 code->
init(app, args);
259 action->
setName(args.value(QStringLiteral(
"name")).toString());
260 action->
setReverse(args.value(QStringLiteral(
"reverse")).toString());
284 if (name == classInfo.
name()) {
297 Action *action = createAction({
307 actions.insertMulti(action->
reverse(), action);
308 actionList.append(action);
316 std::vector<std::pair<QString, QString> > attributes;
323 int size = str.
size();
330 if (str.
at(pos) ==
':') {
331 int keyStart = ++pos;
334 if (str.
at(pos) ==
'(') {
336 int valueStart = ++pos;
338 if (str.
at(pos) ==
')') {
341 if (++pos < size && str.
at(pos) ==
':') {
346 }
else if (pos >= size) {
359 }
else if (str.
at(pos) ==
':') {
388 auto i = attributes.crbegin();
389 const auto end = attributes.crend();
394 key = QStringLiteral(
"Path");
397 key = QStringLiteral(
"Path");
400 value = parsePathAttr(value);
410 value = parseChainedAttr(value);
418 if (!ret.
contains(QStringLiteral(
"Args")) && !ret.
contains(QStringLiteral(
"CaptureArgs")) &&
419 (ret.
contains(QStringLiteral(
"AutoArgs")) || ret.
contains(QStringLiteral(
"AutoCaptureArgs")))) {
420 if (ret.
contains(QStringLiteral(
"AutoArgs")) && ret.
contains(QStringLiteral(
"AutoCaptureArgs"))) {
421 qFatal(
"Action '%s' has both AutoArgs and AutoCaptureArgs, which is not allowed", name.
constData());
424 if (ret.
contains(QStringLiteral(
"AutoArgs"))) {
425 ret.
remove(QStringLiteral(
"AutoArgs"));
426 parameterName = QStringLiteral(
"Args");
428 ret.
remove(QStringLiteral(
"AutoCaptureArgs"));
429 parameterName = QStringLiteral(
"CaptureArgs");
434 int parameterCount = 0;
437 if (typeId == QMetaType::QString) {
448 if (!ret.
contains(QStringLiteral(
"Private")) && method.
access() == QMetaMethod::Private) {
459 auto doesIt = attributes.
constFind(QStringLiteral(
"Does"));
460 while (doesIt != attributes.constEnd() && doesIt.
key() ==
QLatin1String(
"Does")) {
461 QObject *
object = instantiateClass(doesIt.
value(), QByteArrayLiteral(
"Cutelyst::Component"));
463 roles.
push(qobject_cast<Component *>(
object));
483 QString ret = QStringLiteral(
"/");
488 if (attr == QStringLiteral(
".")) {
491 if (!pathPrefix.isEmpty()) {
517 if (!
id && !instanceName.
startsWith(QStringLiteral(
"Cutelyst::"))) {
526 if (!superIsClassName(metaObj->
superClass(), super)) {
527 qCWarning(CUTELYST_CONTROLLER)
530 <<
"is not a derived class of" 536 qCWarning(CUTELYST_CONTROLLER)
537 <<
"Could create a new instance of" 539 <<
"make sure it's default constructor is " 540 "marked with the Q_INVOKABLE macro";
546 Component *component = application->createComponentPlugin(name);
551 component = application->createComponentPlugin(instanceName);
558 qFatal(
"Could not create component '%s', you can register it with qRegisterMetaType<%s>(); or set a proper CUTELYST_PLUGINS_DIR",
559 qPrintable(instanceName), qPrintable(instanceName));
571 return superIsClassName(super->
superClass(), className);
576 #include "moc_controller.cpp" void setName(const QString &name)
QString & append(QChar ch)
bool contains(const Key &key) const
void append(const T &value)
void setReverse(const QString &reverse)
virtual bool preFork(Application *app)
const_iterator constFind(const Key &key) const
Action * actionFor(const QString &name) const
QString & remove(int position, int n)
The Cutelyst Component base class.
This class represents a Cutelyst Action.
QString number(int n, int base)
Cutelyst Controller base class
iterator insertMulti(const Key &key, const T &value)
const char * constData() const
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
virtual bool init(Application *application, const QVariantHash &args)
bool _DISPATCH(Context *c)
The Cutelyst namespace holds all public Cutelyst API.
void applyRoles(const QStack< Component *> &roles)
QByteArray mid(int pos, int len) const
QByteArray & append(char ch)
void setParent(QObject *parent)
QVariant fromValue(const T &value)
void setController(Controller *controller)
virtual bool postFork(Application *app)
const Key key(const T &value, const Key &defaultKey) const
const T & at(int i) const
QByteArray toLatin1() const
void setupAction(const QVariantHash &args, Application *app)
const QChar at(int position) const
QString fromLatin1(const char *str, int size)
bool operator==(const char *className)
The Cutelyst Application.
void setMethod(const QMetaMethod &method)
iterator insert(const Key &key, const T &value)
ActionList actions() const
void attachAsync()
attachAsync
const T value(const Key &key, const T &defaultValue) const
int remove(const Key &key)
Controller(QObject *parent=nullptr)