1 /**
2 * UGENE - Integrated Bioinformatics Tools.
3 * Copyright (C) 2008-2021 UniPro <ugene@unipro.ru>
4 * http://ugene.net
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 * MA 02110-1301, USA.
20 */
21
22 #include "HRWizardSerializer.h"
23
24 #include <U2Core/U2SafePoints.h>
25
26 #include <U2Lang/HRSchemaSerializer.h>
27
28 namespace U2 {
29 namespace WorkflowSerialize {
30
31 const QString HRWizardParser::WIZARD("wizard");
32 const QString HRWizardParser::NAME("name");
33 const QString HRWizardParser::AUTORUN("auto-run");
34 const QString HRWizardParser::PAGE("page");
35 const QString HRWizardParser::ID("id");
36 const QString HRWizardParser::NEXT("next");
37 const QString HRWizardParser::TITLE("title");
38 const QString HRWizardParser::TEMPLATE("template");
39 const QString HRWizardParser::TYPE("type");
40 const QString HRWizardParser::LOGO_PATH("logo-path");
41 const QString HRWizardParser::DEFAULT("default");
42 const QString HRWizardParser::HIDEABLE("hideable");
43 const QString HRWizardParser::LABEL("label");
44 const QString HRWizardParser::LABEL_SIZE("label-size");
45 const QString HRWizardParser::ELEMENT_ID("element-id");
46 const QString HRWizardParser::PROTOTYPE("prototype");
47 const QString HRWizardParser::VALUE("value");
48 const QString HRWizardParser::PORT_MAPPING("port-mapping");
49 const QString HRWizardParser::SLOTS_MAPPRING("slots-mapping");
50 const QString HRWizardParser::SRC_PORT("src-port");
51 const QString HRWizardParser::DST_PORT("dst-port");
52 const QString HRWizardParser::RESULT("result");
53 const QString HRWizardParser::FINISH_LABEL("finish-label");
54 const QString HRWizardParser::TOOLTIP("tooltip");
55 const QString HRWizardParser::HAS_RUN_BUTTON("has-run-button");
56 const QString HRWizardParser::HAS_DEFAULTS_BUTTON("has-defaults-button");
57 const QString HRWizardParser::DATASETS_PROVIDER("datasets-provider");
58 const QString HRWizardParser::TEXT("text");
59 const QString HRWizardParser::TEXT_COLOR("text-color");
60 const QString HRWizardParser::BACKGROUND_COLOR("background-color");
61 const QString HRWizardParser::HELP_PAGE_ID("help-page-id");
62
HRWizardParser(Tokenizer & tokenizer,const QMap<QString,Actor * > & _actorMap)63 HRWizardParser::HRWizardParser(Tokenizer &tokenizer, const QMap<QString, Actor *> &_actorMap)
64 : tokenizer(tokenizer), actorMap(_actorMap), wizardName(Wizard::DEFAULT_NAME) {
65 }
66
~HRWizardParser()67 HRWizardParser::~HRWizardParser() {
68 qDeleteAll(pagesMap);
69 }
70
takeResult()71 Wizard *HRWizardParser::takeResult() {
72 QList<WizardPage *> retPages = pages;
73 pages.clear();
74 pagesMap.clear();
75
76 Wizard *wizard = new Wizard(wizardName, retPages, helpPageId);
77 foreach (const QString &name, vars.keys()) {
78 wizard->addVariable(vars[name]);
79 }
80 foreach (const QString &result, results.keys()) {
81 wizard->addResult(results[result], result);
82 }
83 wizard->setFinishLabel(finishLabel);
84 return wizard;
85 }
86
parseWizard(U2OpStatus & os)87 Wizard *HRWizardParser::parseWizard(U2OpStatus &os) {
88 bool autoRun = false;
89 bool hasRunButton = true;
90 bool hasDefaultsButton = true;
91 while (tokenizer.look() != Constants::BLOCK_END) {
92 QString tok = tokenizer.take();
93 if (PAGE == tok) {
94 tokenizer.assertToken(Constants::BLOCK_START);
95 parsePage(os);
96 CHECK_OP(os, nullptr);
97 tokenizer.assertToken(Constants::BLOCK_END);
98 } else if (NAME == tok) {
99 tokenizer.assertToken(Constants::EQUALS_SIGN);
100 wizardName = tokenizer.take();
101 } else if (HELP_PAGE_ID == tok) {
102 tokenizer.assertToken(Constants::EQUALS_SIGN);
103 helpPageId = tokenizer.take();
104 } else if (AUTORUN == tok) {
105 tokenizer.assertToken(Constants::EQUALS_SIGN);
106 autoRun = ("true" == tokenizer.take());
107 } else if (HAS_RUN_BUTTON == tok) {
108 tokenizer.assertToken(Constants::EQUALS_SIGN);
109 hasRunButton = ("false" != tokenizer.take());
110 } else if (HAS_DEFAULTS_BUTTON == tok) {
111 tokenizer.assertToken(Constants::EQUALS_SIGN);
112 hasDefaultsButton = ("false" != tokenizer.take());
113 } else if (RESULT == tok) {
114 tokenizer.assertToken(Constants::BLOCK_START);
115 parseResult(os);
116 CHECK_OP(os, nullptr);
117 tokenizer.assertToken(Constants::BLOCK_END);
118 } else if (FINISH_LABEL == tok) {
119 tokenizer.assertToken(Constants::EQUALS_SIGN);
120 finishLabel = tokenizer.take();
121 }
122 }
123
124 finilizePagesOrder(os);
125 CHECK_OP(os, nullptr);
126
127 Wizard *result = takeResult();
128 CHECK(nullptr != result, nullptr);
129 result->setAutoRun(autoRun);
130 result->setHasRunButton(hasRunButton);
131 result->setHasDefaultsButton(hasDefaultsButton);
132 return result;
133 }
134
parsePage(U2OpStatus & os)135 void HRWizardParser::parsePage(U2OpStatus &os) {
136 ParsedPairs pairs(tokenizer);
137
138 QString title = pairs.equalPairs.value(TITLE, "");
139 if (!pairs.equalPairs.contains(ID)) {
140 os.setError(tr("Wizard page %1 does not contain id").arg(title));
141 return;
142 }
143 QString id = pairs.equalPairs.take(ID);
144 if (nextIds.keys().contains(id)) {
145 os.setError(tr("Several wizard pages have equal ids: %1").arg(id));
146 return;
147 }
148
149 QString templateId = pairs.equalPairs.value(TEMPLATE, DefaultPageContent::ID);
150 QScopedPointer<TemplatedPageContent> content(PageContentFactory::createContent(templateId, os));
151 CHECK_OP(os, );
152 PageContentParser pcp(pairs, actorMap, vars, os);
153 content->accept(&pcp);
154 CHECK_OP(os, );
155
156 QScopedPointer<WizardPage> page(new WizardPage(id, title));
157 parseNextIds(pairs, page.data(), os);
158 CHECK_OP(os, );
159 page->setContent(content.take());
160 pagesMap[id] = page.take();
161 }
162
parseResult(U2OpStatus & os)163 void HRWizardParser::parseResult(U2OpStatus &os) {
164 ParsedPairs pairs(tokenizer);
165 foreach (const QString &result, pairs.equalPairs.keys()) {
166 QList<Predicate> preds;
167 QStringList tokens = pairs.equalPairs[result].split(" ");
168 for (const QString &predStr : qAsConst(tokens)) {
169 preds << Predicate::fromString(predStr, os);
170 CHECK_OP(os, );
171 }
172 results[result] = preds;
173 }
174 }
175
finilizePagesOrder(U2OpStatus & os)176 void HRWizardParser::finilizePagesOrder(U2OpStatus &os) {
177 // TODO: UGENE-1322
178 Q_UNUSED(os);
179 pages = pagesMap.values();
180 // QString lastId;
181 // QList<QString> ids = nextIds.keys();
182 //// Check loops, first page id and last page id
183 // foreach (const QString &id, nextIds.keys()) {
184 // if (nextIds[id].isEmpty()) {
185 // if (!lastId.isEmpty()) {
186 // os.setError(tr("Two pages of the wizard are defined as last: %1, %2").arg(lastId).arg(id));
187 // return;
188 // }
189 // lastId = id;
190 // } else {
191 // if (!nextIds.keys().contains(nextIds[id])) {
192 // os.setError(tr("Unknown next page id: %1").arg(nextIds[id]));
193 // return;
194 // }
195 // if (!ids.contains(nextIds[id])) {
196 // os.setError(tr("Two pages of the wizard have equal next page ids: %1").arg(nextIds[id]));
197 // return;
198 // }
199 // ids.removeOne(nextIds[id]);
200 // }
201 // }
202 // if (ids.isEmpty()) {
203 // os.setError(tr("Some pages of the widget are looped"));
204 // return;
205 // } else if (ids.size() > 1) {
206 // os.setError(tr("Several pages of the wizard are defined as first: %1, %2, ...").arg(ids[0]).arg(ids[1]));
207 // return;
208 // }
209
210 //// Create pages list saving order
211 // QString currentId = ids.first();
212 // while ("" != currentId) {
213 // QString nextId = nextIds[currentId];
214
215 // WizardPage *page = pagesMap[currentId];
216 // if (!nextId.isEmpty()) {
217 // page->setNext(pagesMap[nextId]->getId());
218 // }
219 // pages << page;
220 // currentId = nextId;
221 //}
222 }
223
parseNextIds(ParsedPairs & pairs,WizardPage * page,U2OpStatus & os)224 void HRWizardParser::parseNextIds(ParsedPairs &pairs, WizardPage *page, U2OpStatus &os) {
225 if (pairs.equalPairs.contains(NEXT)) {
226 QString nextId = pairs.equalPairs.value(NEXT);
227 if (page->getId() == nextId) {
228 os.setError(tr("Page's id and next id are equal: %1").arg(nextId));
229 return;
230 }
231 if (pairs.blockPairs.contains(NEXT)) {
232 os.setError(HRWizardParser::tr("Double definition of next id in the page with id: %1").arg(page->getId()));
233 return;
234 }
235 page->setNext(nextId);
236 return;
237 }
238 if (pairs.blockPairs.contains(NEXT)) {
239 ParsedPairs predPairs(pairs.blockPairs[NEXT]);
240 foreach (const QString &id, predPairs.equalPairs.keys()) {
241 Predicate p = Predicate::fromString(predPairs.equalPairs[id], os);
242 CHECK_OP(os, );
243 page->setNext(id, p, os);
244 CHECK_OP(os, );
245 }
246 }
247 }
248
249 /************************************************************************/
250 /* WizardWidgetParser */
251 /************************************************************************/
WizardWidgetParser(const QString & _title,const QString & _data,const QMap<QString,Actor * > & _actorMap,QMap<QString,Variable> & _vars,U2OpStatus & _os)252 WizardWidgetParser::WizardWidgetParser(const QString &_title,
253 const QString &_data,
254 const QMap<QString, Actor *> &_actorMap,
255 QMap<QString, Variable> &_vars,
256 U2OpStatus &_os)
257 : title(_title), data(_data), actorMap(_actorMap), vars(_vars), os(_os) {
258 }
259
visit(AttributeWidget * aw)260 void WizardWidgetParser::visit(AttributeWidget *aw) {
261 AttributeInfo info = parseInfo(title, data);
262 CHECK_OP(os, );
263 aw->setInfo(info);
264 }
265
visit(WidgetsArea * wa)266 void WizardWidgetParser::visit(WidgetsArea *wa) {
267 pairs = ParsedPairs(data, 0);
268
269 getTitle(wa);
270 getLabelSize(wa);
271
272 foreach (const StrStrPair &pair, pairs.blockPairsList) {
273 WizardWidgetParser wParser(pair.first, pair.second, actorMap, vars, os);
274 QScopedPointer<WizardWidget> w(createWidget(pair.first));
275 CHECK_OP(os, );
276 w->accept(&wParser);
277 CHECK_OP(os, );
278 wa->addWidget(w.take());
279 }
280 }
281
visit(LogoWidget * lw)282 void WizardWidgetParser::visit(LogoWidget *lw) {
283 pairs = ParsedPairs(data, 0);
284 if (pairs.equalPairs.contains(HRWizardParser::LOGO_PATH)) {
285 lw->setLogoPath(pairs.equalPairs.value(HRWizardParser::LOGO_PATH));
286 }
287 }
288
visit(GroupWidget * gw)289 void WizardWidgetParser::visit(GroupWidget *gw) {
290 visit((WidgetsArea *)gw);
291 CHECK_OP(os, );
292
293 QString typeStr = pairs.equalPairs.value(HRWizardParser::TYPE, HRWizardParser::DEFAULT);
294 if (HRWizardParser::DEFAULT == typeStr) {
295 gw->setType(GroupWidget::DEFAULT);
296 } else if (HRWizardParser::HIDEABLE == typeStr) {
297 gw->setType(GroupWidget::HIDEABLE);
298 }
299 }
300
visit(ElementSelectorWidget * esw)301 void WizardWidgetParser::visit(ElementSelectorWidget *esw) {
302 pairs = ParsedPairs(data, 0);
303 if (!pairs.equalPairs.contains(HRWizardParser::ELEMENT_ID)) {
304 os.setError(HRWizardParser::tr("Element id is undefined in the element selector"));
305 return;
306 }
307 QString actorId = pairs.equalPairs[HRWizardParser::ELEMENT_ID];
308 if (!actorMap.contains(actorId)) {
309 os.setError(HRWizardParser::tr("Undefined actor id: %1").arg(actorId));
310 return;
311 }
312 esw->setActorId(actorId);
313 if (pairs.equalPairs.contains(AttributeInfo::LABEL)) {
314 esw->setLabel(pairs.equalPairs[AttributeInfo::LABEL]);
315 }
316 ActorPrototype *srcProto = actorMap[actorId]->getProto();
317 foreach (const StrStrPair &pair, pairs.blockPairsList) {
318 if (pair.first != HRWizardParser::VALUE) {
319 os.setError(HRWizardParser::tr("Unknown block name in element selector definition: %1").arg(pair.first));
320 return;
321 }
322 SelectorValue value = parseSelectorValue(srcProto, pair.second);
323 CHECK_OP(os, );
324 esw->addValue(value);
325 }
326 addVariable(Variable(actorId));
327 CHECK_OP(os, );
328 }
329
visit(PairedReadsWidget * dsw)330 void WizardWidgetParser::visit(PairedReadsWidget *dsw) {
331 pairs = ParsedPairs(data, 0);
332 foreach (const StrStrPair &p, pairs.blockPairsList) {
333 dsw->addInfo(parseInfo(p.first, p.second));
334 CHECK_OP(os, );
335 }
336 }
337
visit(UrlAndDatasetWidget * ldsw)338 void WizardWidgetParser::visit(UrlAndDatasetWidget *ldsw) {
339 pairs = ParsedPairs(data, 0);
340 foreach (const StrStrPair &p, pairs.blockPairsList) {
341 ldsw->addInfo(parseInfo(p.first, p.second));
342 CHECK_OP(os, );
343 }
344 }
345
parseValue(const QString & valueDef,U2OpStatus & os)346 static RadioWidget::Value parseValue(const QString &valueDef, U2OpStatus &os) {
347 ParsedPairs pairs(valueDef, 0);
348 if (!pairs.equalPairs.contains(HRWizardParser::ID)) {
349 os.setError("No id of radio value");
350 return RadioWidget::Value("", "");
351 }
352 QString id = pairs.equalPairs[HRWizardParser::ID];
353 QString label = pairs.equalPairs.value(HRWizardParser::LABEL, id);
354 RadioWidget::Value result(id, label);
355
356 result.tooltip = pairs.equalPairs.value(HRWizardParser::TOOLTIP, "");
357 return result;
358 }
359
serializeValue(const RadioWidget::Value & value,int depth)360 static QString serializeValue(const RadioWidget::Value &value, int depth) {
361 QString vData;
362 vData += HRSchemaSerializer::makeEqualsPair(HRWizardParser::ID, value.id, depth + 1);
363 if (!value.label.isEmpty()) {
364 vData += HRSchemaSerializer::makeEqualsPair(HRWizardParser::LABEL, value.label, depth + 1);
365 }
366 if (!value.tooltip.isEmpty()) {
367 vData += HRSchemaSerializer::makeEqualsPair(HRWizardParser::TOOLTIP, value.tooltip, depth + 1);
368 }
369
370 return HRSchemaSerializer::makeBlock(HRWizardParser::VALUE, Constants::NO_NAME, vData, depth);
371 }
372
visit(RadioWidget * rw)373 void WizardWidgetParser::visit(RadioWidget *rw) {
374 pairs = ParsedPairs(data, 0);
375 if (!pairs.equalPairs.contains(HRWizardParser::ID)) {
376 os.setError("No id of radio");
377 return;
378 }
379
380 rw->setVar(pairs.equalPairs[HRWizardParser::ID]);
381 Variable v(rw->var());
382 foreach (const StrStrPair &p, pairs.blockPairsList) {
383 if (p.first == HRWizardParser::VALUE) {
384 RadioWidget::Value value = parseValue(p.second, os);
385 CHECK_OP(os, );
386 rw->add(value);
387 if (!v.isAssigned()) {
388 v.setValue(value.id);
389 }
390 }
391 }
392
393 addVariable(v);
394 CHECK_OP(os, );
395 }
396
visit(SettingsWidget * sw)397 void WizardWidgetParser::visit(SettingsWidget *sw) {
398 pairs = ParsedPairs(data, 0);
399 if (!pairs.equalPairs.contains(HRWizardParser::ID)) {
400 os.setError("No id of settings-widget");
401 return;
402 }
403
404 sw->setVar(SettingsWidget::SETTING_PREFIX + pairs.equalPairs[HRWizardParser::ID]);
405 sw->setType(pairs.equalPairs[HRWizardParser::TYPE]);
406 sw->setLabel(pairs.equalPairs[HRWizardParser::LABEL]);
407 Variable v(sw->var());
408
409 addVariable(v);
410 CHECK_OP(os, );
411 }
412
visit(BowtieWidget * bw)413 void WizardWidgetParser::visit(BowtieWidget *bw) {
414 pairs = ParsedPairs(data, 0);
415 if (pairs.blockPairsList.size() != 2) {
416 os.setError("Not enough attributes for Bowtie index widget");
417 return;
418 }
419 bw->idxDir = parseInfo(pairs.blockPairsList[0].first, pairs.blockPairsList[0].second);
420 CHECK_OP(os, );
421 bw->idxName = parseInfo(pairs.blockPairsList[1].first, pairs.blockPairsList[1].second);
422 CHECK_OP(os, );
423 }
424
visit(TophatSamplesWidget * tsw)425 void WizardWidgetParser::visit(TophatSamplesWidget *tsw) {
426 pairs = ParsedPairs(data, 0);
427 if (!pairs.equalPairs.contains(HRWizardParser::DATASETS_PROVIDER)) {
428 os.setError(HRWizardParser::tr("Not enough attributes for Tophat samples widget"));
429 return;
430 }
431 if (1 != pairs.blockPairsList.size()) {
432 os.setError(HRWizardParser::tr("Not enough attributes for Tophat samples widget"));
433 return;
434 }
435 tsw->datasetsProvider = pairs.equalPairs[HRWizardParser::DATASETS_PROVIDER];
436 tsw->samplesAttr = parseInfo(pairs.blockPairsList[0].first, pairs.blockPairsList[0].second);
437 }
438
visit(LabelWidget * lw)439 void WizardWidgetParser::visit(LabelWidget *lw) {
440 pairs = ParsedPairs(data, 0);
441 if (!pairs.equalPairs.contains(HRWizardParser::TEXT)) {
442 os.setError(HRWizardParser::tr("Not enough attributes for the label widget"));
443 return;
444 }
445 lw->text = pairs.equalPairs[HRWizardParser::TEXT];
446
447 if (pairs.equalPairs.contains(HRWizardParser::TEXT_COLOR)) {
448 lw->textColor = pairs.equalPairs[HRWizardParser::TEXT_COLOR];
449 }
450 if (pairs.equalPairs.contains(HRWizardParser::BACKGROUND_COLOR)) {
451 lw->backgroundColor = pairs.equalPairs[HRWizardParser::BACKGROUND_COLOR];
452 }
453 }
454
parseSelectorValue(ActorPrototype * srcProto,const QString & valueDef)455 SelectorValue WizardWidgetParser::parseSelectorValue(ActorPrototype *srcProto, const QString &valueDef) {
456 ParsedPairs pairs(valueDef, 0);
457 if (!pairs.equalPairs.contains(HRWizardParser::ID)) {
458 os.setError(HRWizardParser::tr("Id is undefined in some selector value definition"));
459 return SelectorValue("", "");
460 }
461 QString id = pairs.equalPairs[HRWizardParser::ID];
462 if (!pairs.equalPairs.contains(HRWizardParser::PROTOTYPE)) {
463 os.setError(HRWizardParser::tr("Prototype is undefined in the selector value definition: %1").arg(id));
464 return SelectorValue("", "");
465 }
466 QString protoId = pairs.equalPairs[HRWizardParser::PROTOTYPE];
467 SelectorValue result(id, protoId);
468 result.setName(pairs.equalPairs[HRWizardParser::NAME]);
469 if (srcProto->getId() == protoId) {
470 if (!pairs.blockPairsList.isEmpty()) {
471 os.setError(HRWizardParser::tr("The same prototype could not be mapped: %1").arg(protoId));
472 }
473 return result;
474 }
475 foreach (const StrStrPair &pair, pairs.blockPairsList) {
476 if (pair.first != HRWizardParser::PORT_MAPPING) {
477 os.setError(HRWizardParser::tr("Unknown block name in selector value definition: %1").arg(pair.first));
478 return result;
479 }
480 PortMapping mapping = parsePortMapping(pair.second);
481 CHECK_OP(os, result);
482 result.addPortMapping(mapping);
483 }
484 return result;
485 }
486
parsePortMapping(const QString & mappingDef)487 PortMapping WizardWidgetParser::parsePortMapping(const QString &mappingDef) {
488 ParsedPairs pairs(mappingDef, 0);
489 if (!pairs.equalPairs.contains(HRWizardParser::SRC_PORT)) {
490 os.setError(HRWizardParser::tr("Undefined source port id for some port mapping"));
491 return PortMapping("", "");
492 }
493 if (!pairs.equalPairs.contains(HRWizardParser::DST_PORT)) {
494 os.setError(HRWizardParser::tr("Undefined destination port id for some port mapping"));
495 return PortMapping("", "");
496 }
497 QString srcPortId = pairs.equalPairs[HRWizardParser::SRC_PORT];
498 QString dstPortId = pairs.equalPairs[HRWizardParser::DST_PORT];
499 PortMapping result(srcPortId, dstPortId);
500 foreach (const StrStrPair &pair, pairs.blockPairsList) {
501 if (pair.first != HRWizardParser::SLOTS_MAPPRING) {
502 os.setError(HRWizardParser::tr("Unknown block name in port mapping definition: %1").arg(pair.first));
503 return result;
504 }
505 parseSlotsMapping(result, pair.second);
506 CHECK_OP(os, result);
507 }
508 return result;
509 }
510
parseSlotsMapping(PortMapping & pm,const QString & mappingDef)511 void WizardWidgetParser::parseSlotsMapping(PortMapping &pm, const QString &mappingDef) {
512 ParsedPairs pairs(mappingDef, 0);
513 foreach (const StrStrPair &pair, pairs.equalPairsList) {
514 QString srcSlotId = pair.first;
515 QString dstSlotId = pair.second;
516 pm.addSlotMapping(SlotMapping(srcSlotId, dstSlotId));
517 }
518 }
519
getLabelSize(WidgetsArea * wa)520 void WizardWidgetParser::getLabelSize(WidgetsArea *wa) {
521 if (pairs.equalPairs.contains(HRWizardParser::LABEL_SIZE)) {
522 QString &sizeStr = pairs.equalPairs[HRWizardParser::LABEL_SIZE];
523 bool ok = true;
524 int size = sizeStr.toInt(&ok);
525 if (!ok) {
526 os.setError(QObject::tr("Wrong label size value: %1").arg(sizeStr));
527 return;
528 }
529 wa->setLabelSize(size);
530 }
531 }
532
getTitle(WidgetsArea * wa)533 void WizardWidgetParser::getTitle(WidgetsArea *wa) {
534 if (pairs.equalPairs.contains(HRWizardParser::TITLE)) {
535 wa->setTitle(pairs.equalPairs[HRWizardParser::TITLE]);
536 }
537 }
538
createWidget(const QString & id)539 WizardWidget *WizardWidgetParser::createWidget(const QString &id) {
540 if (LogoWidget::ID == id) {
541 return new LogoWidget();
542 } else if (GroupWidget::ID == id) {
543 return new GroupWidget();
544 } else if (ElementSelectorWidget::ID == id) {
545 return new ElementSelectorWidget();
546 } else if (PairedReadsWidget::ID == id) {
547 return new PairedReadsWidget();
548 } else if (UrlAndDatasetWidget::ID == id) {
549 return new UrlAndDatasetWidget();
550 } else if (RadioWidget::ID == id) {
551 return new RadioWidget();
552 } else if (SettingsWidget::ID == id) {
553 return new SettingsWidget();
554 } else if (BowtieWidget::ID == id) {
555 return new BowtieWidget();
556 } else if (TophatSamplesWidget::ID == id) {
557 return new TophatSamplesWidget();
558 } else if (LabelWidget::ID == id) {
559 return new LabelWidget();
560 } else {
561 return new AttributeWidget();
562 }
563 }
564
addVariable(const Variable & v)565 void WizardWidgetParser::addVariable(const Variable &v) {
566 if (vars.contains(v.getName())) {
567 os.setError(QObject::tr("The variable is already defined: %1").arg(v.getName()));
568 return;
569 }
570 vars[v.getName()] = v;
571 }
572
parseInfo(const QString & attrStr,const QString & body)573 AttributeInfo WizardWidgetParser::parseInfo(const QString &attrStr, const QString &body) {
574 QStringList vals = attrStr.split(Constants::DOT, QString::SkipEmptyParts);
575 if (2 != vals.size()) {
576 os.setError(HRWizardParser::tr("Unknown widget name: %1").arg(attrStr));
577 return AttributeInfo("", "");
578 }
579
580 ParsedPairs pairs = ParsedPairs(body, 0);
581 QVariantMap hints;
582 foreach (const QString &id, pairs.equalPairs.keys()) {
583 hints[id] = pairs.equalPairs[id];
584 }
585
586 return AttributeInfo(vals[0], vals[1], hints);
587 }
588
589 /************************************************************************/
590 /* PageContentParser */
591 /************************************************************************/
PageContentParser(ParsedPairs & pairs,const QMap<QString,Actor * > & actorMap,QMap<QString,Variable> & vars,U2OpStatus & os)592 PageContentParser::PageContentParser(ParsedPairs &pairs,
593 const QMap<QString, Actor *> &actorMap,
594 QMap<QString, Variable> &vars,
595 U2OpStatus &os)
596 : pairs(pairs), actorMap(actorMap), vars(vars), os(os) {
597 }
598
visit(DefaultPageContent * content)599 void PageContentParser::visit(DefaultPageContent *content) {
600 foreach (const StrStrPair &pair, pairs.blockPairsList) {
601 WizardWidgetParser wParser(pair.first, pair.second, actorMap, vars, os);
602 if (LogoWidget::ID == pair.first) {
603 content->getLogoArea()->accept(&wParser);
604 } else if (DefaultPageContent::PARAMETERS == pair.first) {
605 content->getParamsArea()->accept(&wParser);
606 }
607 CHECK_OP(os, );
608 }
609 }
610
611 /************************************************************************/
612 /* HRWizardSerializer */
613 /************************************************************************/
serialize(Wizard * wizard,int depth)614 QString HRWizardSerializer::serialize(Wizard *wizard, int depth) {
615 QString wizardData;
616
617 if (Wizard::DEFAULT_NAME != wizard->getName()) {
618 wizardData += HRSchemaSerializer::makeEqualsPair(HRWizardParser::NAME,
619 wizard->getName(),
620 depth + 1);
621 }
622
623 if (wizard->isAutoRun()) {
624 wizardData += HRSchemaSerializer::makeEqualsPair(HRWizardParser::AUTORUN, "true", depth + 1);
625 }
626
627 if (!wizard->hasRunButton()) {
628 wizardData += HRSchemaSerializer::makeEqualsPair(HRWizardParser::HAS_RUN_BUTTON, "false", depth + 1);
629 }
630 if (!wizard->hasDefaultsButton()) {
631 wizardData += HRSchemaSerializer::makeEqualsPair(HRWizardParser::HAS_DEFAULTS_BUTTON, "false", depth + 1);
632 }
633
634 if (!wizard->getResults().isEmpty()) {
635 wizardData += serializeResults(wizard->getResults(), depth + 1);
636 }
637
638 foreach (WizardPage *page, wizard->getPages()) {
639 wizardData += serializePage(page, depth + 1);
640 }
641
642 return HRSchemaSerializer::makeBlock(HRWizardParser::WIZARD,
643 Constants::NO_NAME,
644 wizardData,
645 depth);
646 }
647
serializePage(WizardPage * page,int depth)648 QString HRWizardSerializer::serializePage(WizardPage *page, int depth) {
649 QString pageData;
650
651 pageData += HRSchemaSerializer::makeEqualsPair(HRWizardParser::ID, page->getId(), depth + 1);
652 pageData += HRWizardSerializer::serializeNextId(page, depth + 1);
653 if (!page->getTitle().isEmpty()) {
654 pageData += HRSchemaSerializer::makeEqualsPair(HRWizardParser::TITLE,
655 page->getTitle(),
656 depth + 1);
657 }
658 if (DefaultPageContent::ID != page->getContent()->getTemplateId()) {
659 pageData += HRSchemaSerializer::makeEqualsPair(HRWizardParser::TEMPLATE,
660 page->getContent()->getTemplateId(),
661 depth + 1);
662 }
663
664 PageContentSerializer cs(depth + 1);
665 page->getContent()->accept(&cs);
666 pageData += cs.getResult();
667
668 return HRSchemaSerializer::makeBlock(HRWizardParser::PAGE,
669 Constants::NO_NAME,
670 pageData,
671 depth);
672 }
673
serializeResults(const QMap<QString,QList<Predicate>> results,int depth)674 QString HRWizardSerializer::serializeResults(const QMap<QString, QList<Predicate>> results, int depth) {
675 QString rData;
676
677 foreach (const QString &result, results.keys()) {
678 QStringList preds;
679 const QList<Predicate> &predicates = results[result];
680 for (const Predicate &p : qAsConst(predicates)) {
681 preds << p.toString();
682 }
683 QString predsStr = preds.join(" ");
684 rData += HRSchemaSerializer::makeEqualsPair(result, predsStr, depth + 1);
685 }
686
687 return HRSchemaSerializer::makeBlock(HRWizardParser::RESULT,
688 Constants::NO_NAME,
689 rData,
690 depth);
691 }
692
serializeNextId(WizardPage * page,int depth)693 QString HRWizardSerializer::serializeNextId(WizardPage *page, int depth) {
694 if (page->nextIdMap().isEmpty()) {
695 if (page->plainNextId().isEmpty()) {
696 return "";
697 }
698 return HRSchemaSerializer::makeEqualsPair(HRWizardParser::NEXT, page->plainNextId(), depth);
699 }
700 QString nextData;
701 foreach (const Predicate &p, page->nextIdMap().keys()) {
702 QString id = page->nextIdMap()[p];
703 nextData += HRSchemaSerializer::makeEqualsPair(id, p.toString(), depth + 1);
704 }
705 return HRSchemaSerializer::makeBlock(HRWizardParser::NEXT,
706 Constants::NO_NAME,
707 nextData,
708 depth);
709 }
710
711 /************************************************************************/
712 /* WizardWidgetSerializer */
713 /************************************************************************/
WizardWidgetSerializer(int _depth)714 WizardWidgetSerializer::WizardWidgetSerializer(int _depth)
715 : depth(_depth) {
716 }
717
visit(AttributeWidget * aw)718 void WizardWidgetSerializer::visit(AttributeWidget *aw) {
719 result = serializeInfo(aw->getInfo(), depth);
720 }
721
visit(WidgetsArea * wa)722 void WizardWidgetSerializer::visit(WidgetsArea *wa) {
723 QString wData;
724 // write title
725 if (!wa->getTitle().isEmpty()) {
726 wData += HRSchemaSerializer::makeEqualsPair(HRWizardParser::TITLE,
727 wa->getTitle(),
728 depth + 1);
729 }
730 // write label size
731 if (wa->hasLabelSize()) {
732 wData += HRSchemaSerializer::makeEqualsPair(HRWizardParser::LABEL_SIZE,
733 QString::number(wa->getLabelSize()),
734 depth + 1);
735 }
736 // write additional info
737 wData += addInfo;
738 // write widgets
739 foreach (WizardWidget *w, wa->getWidgets()) {
740 WizardWidgetSerializer ws(depth + 1);
741 w->accept(&ws);
742 wData += ws.getResult();
743 }
744
745 result = HRSchemaSerializer::makeBlock(wa->getName(),
746 Constants::NO_NAME,
747 wData,
748 depth);
749 }
750
visit(GroupWidget * gw)751 void WizardWidgetSerializer::visit(GroupWidget *gw) {
752 if (GroupWidget::HIDEABLE == gw->getType()) {
753 addInfo = HRSchemaSerializer::makeEqualsPair(HRWizardParser::TYPE,
754 HRWizardParser::HIDEABLE,
755 depth + 1);
756 }
757 visit((WidgetsArea *)gw);
758 }
759
visit(LogoWidget * lw)760 void WizardWidgetSerializer::visit(LogoWidget *lw) {
761 QString wData;
762 if (!lw->isDefault()) {
763 wData += HRSchemaSerializer::makeEqualsPair(HRWizardParser::LOGO_PATH,
764 lw->getLogoPath(),
765 depth + 1);
766 }
767 result = HRSchemaSerializer::makeBlock(LogoWidget::ID,
768 Constants::NO_NAME,
769 wData,
770 depth);
771 }
772
visit(ElementSelectorWidget * esw)773 void WizardWidgetSerializer::visit(ElementSelectorWidget *esw) {
774 QString wData;
775 wData += HRSchemaSerializer::makeEqualsPair(HRWizardParser::ELEMENT_ID,
776 esw->getActorId(),
777 depth + 1);
778 if (!esw->getLabel().isEmpty()) {
779 wData += HRSchemaSerializer::makeEqualsPair(AttributeInfo::LABEL,
780 esw->getLabel(),
781 depth + 1);
782 }
783 foreach (const SelectorValue &value, esw->getValues()) {
784 wData += serializeSelectorValue(value, depth + 1);
785 }
786 result = HRSchemaSerializer::makeBlock(ElementSelectorWidget::ID,
787 Constants::NO_NAME,
788 wData,
789 depth);
790 }
791
visit(PairedReadsWidget * dsw)792 void WizardWidgetSerializer::visit(PairedReadsWidget *dsw) {
793 QString dData;
794 foreach (const AttributeInfo &info, dsw->getInfos()) {
795 dData += serializeInfo(info, depth + 1);
796 }
797 result = HRSchemaSerializer::makeBlock(PairedReadsWidget::ID,
798 Constants::NO_NAME,
799 dData,
800 depth);
801 }
802
visit(UrlAndDatasetWidget * ldsw)803 void WizardWidgetSerializer::visit(UrlAndDatasetWidget *ldsw) {
804 QString dData;
805 foreach (const AttributeInfo &info, ldsw->getInfos()) {
806 dData += serializeInfo(info, depth + 1);
807 }
808 result = HRSchemaSerializer::makeBlock(UrlAndDatasetWidget::ID,
809 Constants::NO_NAME,
810 dData,
811 depth);
812 }
813
visit(RadioWidget * rw)814 void WizardWidgetSerializer::visit(RadioWidget *rw) {
815 QString rData;
816 rData += HRSchemaSerializer::makeEqualsPair(HRWizardParser::ID, rw->var(), depth + 1);
817 foreach (const RadioWidget::Value &value, rw->values()) {
818 rData += serializeValue(value, depth + 1);
819 }
820 result = HRSchemaSerializer::makeBlock(RadioWidget::ID,
821 Constants::NO_NAME,
822 rData,
823 depth);
824 }
825
visit(SettingsWidget * sw)826 void WizardWidgetSerializer::visit(SettingsWidget *sw) {
827 QString rData;
828 QString var = sw->var();
829 if (var.startsWith(SettingsWidget::SETTING_PREFIX)) {
830 var.remove(0, SettingsWidget::SETTING_PREFIX.length());
831 }
832
833 rData += HRSchemaSerializer::makeEqualsPair(HRWizardParser::ID, var, depth + 1);
834 rData += HRSchemaSerializer::makeEqualsPair(HRWizardParser::TYPE, sw->type(), depth + 1);
835 rData += HRSchemaSerializer::makeEqualsPair(HRWizardParser::LABEL, sw->label(), depth + 1);
836 result = HRSchemaSerializer::makeBlock(SettingsWidget::ID,
837 Constants::NO_NAME,
838 rData,
839 depth);
840 }
841
visit(BowtieWidget * bw)842 void WizardWidgetSerializer::visit(BowtieWidget *bw) {
843 QString bData;
844 bData += serializeInfo(bw->idxDir, depth + 1);
845 bData += serializeInfo(bw->idxName, depth + 1);
846 result = HRSchemaSerializer::makeBlock(BowtieWidget::ID,
847 Constants::NO_NAME,
848 bData,
849 depth);
850 }
851
visit(TophatSamplesWidget * tsw)852 void WizardWidgetSerializer::visit(TophatSamplesWidget *tsw) {
853 QString tsData;
854 tsData += HRSchemaSerializer::makeEqualsPair(HRWizardParser::DATASETS_PROVIDER,
855 tsw->datasetsProvider,
856 depth + 1);
857 tsData += serializeInfo(tsw->samplesAttr, depth + 1);
858
859 result = HRSchemaSerializer::makeBlock(TophatSamplesWidget::ID,
860 Constants::NO_NAME,
861 tsData,
862 depth);
863 }
864
visit(LabelWidget * lw)865 void WizardWidgetSerializer::visit(LabelWidget *lw) {
866 QString lData;
867 lData += HRSchemaSerializer::makeEqualsPair(HRWizardParser::TEXT, lw->text, depth + 1);
868 if (lw->backgroundColor != LabelWidget::DEFAULT_BG_COLOR) {
869 lData += HRSchemaSerializer::makeEqualsPair(HRWizardParser::BACKGROUND_COLOR, lw->backgroundColor, depth + 1);
870 }
871 if (lw->textColor != LabelWidget::DEFAULT_TEXT_COLOR) {
872 lData += HRSchemaSerializer::makeEqualsPair(HRWizardParser::TEXT_COLOR, lw->textColor, depth + 1);
873 }
874 result = HRSchemaSerializer::makeBlock(LabelWidget::ID, Constants::NO_NAME, lData, depth);
875 }
876
serializeSlotsMapping(const QList<SlotMapping> & mappings,int depth) const877 QString WizardWidgetSerializer::serializeSlotsMapping(const QList<SlotMapping> &mappings, int depth) const {
878 QString smData;
879 foreach (const SlotMapping &mapping, mappings) {
880 smData += HRSchemaSerializer::makeEqualsPair(mapping.getSrcId(),
881 mapping.getDstId(),
882 depth + 1);
883 }
884 return HRSchemaSerializer::makeBlock(HRWizardParser::SLOTS_MAPPRING,
885 Constants::NO_NAME,
886 smData,
887 depth);
888 }
889
serializePortMapping(const PortMapping & mapping,int depth) const890 QString WizardWidgetSerializer::serializePortMapping(const PortMapping &mapping, int depth) const {
891 QString pmData;
892 pmData += HRSchemaSerializer::makeEqualsPair(HRWizardParser::SRC_PORT,
893 mapping.getSrcId(),
894 depth + 1);
895 pmData += HRSchemaSerializer::makeEqualsPair(HRWizardParser::DST_PORT,
896 mapping.getDstId(),
897 depth + 1);
898 pmData += serializeSlotsMapping(mapping.getMappings(), depth + 1);
899 return HRSchemaSerializer::makeBlock(HRWizardParser::PORT_MAPPING,
900 Constants::NO_NAME,
901 pmData,
902 depth);
903 }
904
serializeSelectorValue(const SelectorValue & value,int depth) const905 QString WizardWidgetSerializer::serializeSelectorValue(const SelectorValue &value, int depth) const {
906 QString vData;
907 vData += HRSchemaSerializer::makeEqualsPair(HRWizardParser::ID,
908 value.getValue(),
909 depth + 1);
910 vData += HRSchemaSerializer::makeEqualsPair(HRWizardParser::PROTOTYPE,
911 value.getProtoId(),
912 depth + 1);
913 if (!value.getName().isEmpty()) {
914 vData += HRSchemaSerializer::makeEqualsPair(HRWizardParser::NAME,
915 value.getName(),
916 depth + 1);
917 }
918 foreach (const PortMapping &mapping, value.getMappings()) {
919 vData += serializePortMapping(mapping, depth + 1);
920 }
921 return HRSchemaSerializer::makeBlock(HRWizardParser::VALUE,
922 Constants::NO_NAME,
923 vData,
924 depth);
925 }
926
serializeInfo(const AttributeInfo & info,int depth) const927 QString WizardWidgetSerializer::serializeInfo(const AttributeInfo &info, int depth) const {
928 QString iData;
929
930 foreach (const QString &id, info.hints.keys()) {
931 QString value = info.hints[id].toString();
932 if (!value.isEmpty()) {
933 iData += HRSchemaSerializer::makeEqualsPair(id, value, depth + 1);
934 }
935 }
936
937 QString name = info.actorId + Constants::DOT + info.attrId;
938 return HRSchemaSerializer::makeBlock(name, Constants::NO_NAME, iData, depth);
939 }
940
getResult()941 const QString &WizardWidgetSerializer::getResult() {
942 return result;
943 }
944
945 /************************************************************************/
946 /* PageContentSerializer */
947 /************************************************************************/
PageContentSerializer(int _depth)948 PageContentSerializer::PageContentSerializer(int _depth)
949 : depth(_depth) {
950 }
951
visit(DefaultPageContent * content)952 void PageContentSerializer::visit(DefaultPageContent *content) {
953 WizardWidgetSerializer pws(depth);
954 content->getParamsArea()->accept(&pws);
955 result += pws.getResult();
956
957 if (!content->getLogoArea()->isDefault()) {
958 WizardWidgetSerializer lws(depth);
959 content->getLogoArea()->accept(&lws);
960 result += lws.getResult();
961 }
962 }
963
getResult() const964 const QString &PageContentSerializer::getResult() const {
965 return result;
966 }
967
968 } // namespace WorkflowSerialize
969 } // namespace U2
970