comparison OrthancFramework/Sources/RestApi/RestApi.cpp @ 4413:22a1352a0823

cont openapi
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 28 Dec 2020 13:08:00 +0100
parents 68b96234fbd6
children d928dfcacb4b
comparison
equal deleted inserted replaced
4412:68b96234fbd6 4413:22a1352a0823
423 { 423 {
424 private: 424 private:
425 class Path 425 class Path
426 { 426 {
427 private: 427 private:
428 std::string tag_;
429 bool hasGet_; 428 bool hasGet_;
430 bool hasPost_; 429 bool hasPost_;
431 bool hasDelete_; 430 bool hasDelete_;
432 bool hasPut_; 431 bool hasPut_;
432 std::string getTag_;
433 std::string postTag_;
434 std::string deleteTag_;
435 std::string putTag_;
433 std::string summary_; 436 std::string summary_;
434 HttpMethod summaryOrigin_; 437 HttpMethod summaryOrigin_;
435 438
436 public: 439 public:
437 Path() : 440 Path() :
441 hasPut_(false), 444 hasPut_(false),
442 summaryOrigin_(HttpMethod_Get) // Dummy initialization 445 summaryOrigin_(HttpMethod_Get) // Dummy initialization
443 { 446 {
444 } 447 }
445 448
446 void AddMethod(HttpMethod method) 449 void AddMethod(HttpMethod method,
450 const std::string& tag)
447 { 451 {
448 switch (method) 452 switch (method)
449 { 453 {
450 case HttpMethod_Get: 454 case HttpMethod_Get:
455 if (hasGet_)
456 {
457 throw OrthancException(ErrorCode_InternalError);
458 }
459
451 hasGet_ = true; 460 hasGet_ = true;
461 getTag_ = tag;
452 break; 462 break;
453 463
454 case HttpMethod_Post: 464 case HttpMethod_Post:
465 if (hasPost_)
466 {
467 throw OrthancException(ErrorCode_InternalError);
468 }
469
455 hasPost_ = true; 470 hasPost_ = true;
471 postTag_ = tag;
456 break; 472 break;
457 473
458 case HttpMethod_Delete: 474 case HttpMethod_Delete:
475 if (hasDelete_)
476 {
477 throw OrthancException(ErrorCode_InternalError);
478 }
479
459 hasDelete_ = true; 480 hasDelete_ = true;
481 deleteTag_ = tag;
460 break; 482 break;
461 483
462 case HttpMethod_Put: 484 case HttpMethod_Put:
485 if (hasPut_)
486 {
487 throw OrthancException(ErrorCode_InternalError);
488 }
489
463 hasPut_ = true; 490 hasPut_ = true;
491 putTag_ = tag;
464 break; 492 break;
465 493
466 default: 494 default:
467 throw OrthancException(ErrorCode_ParameterOutOfRange); 495 throw OrthancException(ErrorCode_ParameterOutOfRange);
468 } 496 }
469 } 497 }
470 498
471 bool HasSummary() const 499 void SetSummary(const std::string& summary,
472 {
473 return !summary_.empty();
474 }
475
476 const std::string& GetTag() const
477 {
478 return tag_;
479 }
480
481 void SetSummary(const std::string& tag,
482 const std::string& summary,
483 HttpMethod newOrigin) 500 HttpMethod newOrigin)
484 { 501 {
485 if (!tag_.empty() &&
486 !tag.empty() &&
487 tag_ != tag)
488 {
489 printf("===================================================================================\n");
490 throw OrthancException(ErrorCode_InternalError, "Mismatch between HTTP methods in the tag: \"" +
491 tag + "\" vs. \"" + tag_ + "\"");
492 }
493
494 if (tag_.empty())
495 {
496 tag_ = tag;
497 }
498
499 if (!summary.empty()) 502 if (!summary.empty())
500 { 503 {
501 bool replace; 504 bool replace;
502 505
503 if (summary_.empty()) 506 if (summary_.empty())
542 summaryOrigin_ = newOrigin; 545 summaryOrigin_ = newOrigin;
543 } 546 }
544 } 547 }
545 } 548 }
546 549
547 bool HasGet() const
548 {
549 return hasGet_;
550 }
551
552 bool HasPost() const
553 {
554 return hasPost_;
555 }
556
557 bool HasDelete() const
558 {
559 return hasDelete_;
560 }
561
562 bool HasPut() const
563 {
564 return hasPut_;
565 }
566
567 const std::string& GetSummary() const 550 const std::string& GetSummary() const
568 { 551 {
569 return summary_; 552 return summary_;
570 } 553 }
554
555 static std::string FormatTag(const std::string& tag)
556 {
557 if (tag.empty())
558 {
559 return tag;
560 }
561 else
562 {
563 std::string s;
564 s.reserve(tag.size());
565 s.push_back(tag[0]);
566
567 for (size_t i = 1; i < tag.size(); i++)
568 {
569 if (tag[i] == ' ')
570 {
571 s.push_back('-');
572 }
573 else if (isupper(tag[i]) &&
574 tag[i - 1] == ' ')
575 {
576 s.push_back(tolower(tag[i]));
577 }
578 else
579 {
580 s.push_back(tag[i]);
581 }
582 }
583
584 return s;
585 }
586 }
587
588 std::string Format(const std::string& openApiUrl,
589 HttpMethod method,
590 const std::string& uri) const
591 {
592 std::string p = uri;
593 boost::replace_all(p, "/", "~1");
594
595 switch (method)
596 {
597 case HttpMethod_Get:
598 if (hasGet_)
599 {
600 if (openApiUrl.empty())
601 {
602 return "GET";
603 }
604 else
605 {
606 return ("`GET <" + openApiUrl + "#tag/" + FormatTag(getTag_) + "/paths/" + p + "/get>`__");
607 }
608 }
609 break;
610
611 case HttpMethod_Post:
612 if (hasPost_)
613 {
614 if (openApiUrl.empty())
615 {
616 return "POST";
617 }
618 else
619 {
620 return ("`POST <" + openApiUrl + "#tag/" + FormatTag(postTag_) + "/paths/" + p + "/post>`__");
621 }
622 }
623 break;
624
625 case HttpMethod_Delete:
626 if (hasDelete_)
627 {
628 if (openApiUrl.empty())
629 {
630 return "DELETE";
631 }
632 else
633 {
634 return ("`DELETE <" + openApiUrl + "#tag/" + FormatTag(deleteTag_) + "/paths/" + p + "/delete>`__");
635 }
636 }
637 break;
638
639 case HttpMethod_Put:
640 if (hasPut_)
641 {
642 if (openApiUrl.empty())
643 {
644 return "GET";
645 }
646 else
647 {
648 return ("`PUT <" + openApiUrl + "#tag/" + FormatTag(putTag_) + "/paths/" + p + "/put>`__");
649 }
650 }
651 break;
652
653 default:
654 throw OrthancException(ErrorCode_InternalError);
655 }
656
657 return "";
658 }
571 }; 659 };
572 660
573 typedef std::map<std::string, Path> Paths; 661 typedef std::map<std::string, Path> Paths;
574 662
575 Paths paths_; 663 Paths paths_;
576
577 static std::string FormatTag(const std::string& tag)
578 {
579 if (tag.empty())
580 {
581 return tag;
582 }
583 else
584 {
585 std::string s;
586 s.reserve(tag.size());
587 s.push_back(tag[0]);
588
589 for (size_t i = 1; i < tag.size(); i++)
590 {
591 if (tag[i] == ' ')
592 {
593 s.push_back('-');
594 }
595 else if (isupper(tag[i]) &&
596 tag[i - 1] == ' ')
597 {
598 s.push_back(tolower(tag[i]));
599 }
600 else
601 {
602 s.push_back(tag[i]);
603 }
604 }
605
606 return s;
607 }
608 }
609
610 std::string FormatUrl(const std::string& openApiUrl,
611 bool hasMethod,
612 const std::string& tag,
613 const std::string& uri,
614 const std::string& method) const
615 {
616 if (hasMethod)
617 {
618 std::string title;
619 Toolbox::ToUpperCase(title, method);
620
621 if (openApiUrl.empty())
622 {
623 return title;
624 }
625 else
626 {
627 std::string p = uri;
628 boost::replace_all(p, "/", "~1");
629
630 return ("`" + title + " <" + openApiUrl + "#tag/" +
631 FormatTag(tag) + "/paths/" + p + "/" + method + ">`__");
632 }
633 }
634 else
635 {
636 return "";
637 }
638 }
639 664
640 protected: 665 protected:
641 virtual bool HandleCall(RestApiCall& call, 666 virtual bool HandleCall(RestApiCall& call,
642 const std::set<std::string> uriArgumentsNames) ORTHANC_OVERRIDE 667 const std::set<std::string> uriArgumentsNames) ORTHANC_OVERRIDE
643 { 668 {
644 Path& path = paths_[ Toolbox::FlattenUri(call.GetFullUri()) ]; 669 Path& path = paths_[ Toolbox::FlattenUri(call.GetFullUri()) ];
645 670
646 path.AddMethod(call.GetMethod()); 671 path.AddMethod(call.GetMethod(), call.GetDocumentation().GetTag());
647 672
648 if (call.GetDocumentation().HasSummary()) 673 if (call.GetDocumentation().HasSummary())
649 { 674 {
650 path.SetSummary(call.GetDocumentation().GetTag(), call.GetDocumentation().GetSummary(), call.GetMethod()); 675 path.SetSummary(call.GetDocumentation().GetSummary(), call.GetMethod());
651 } 676 }
652 677
653 return true; 678 return true;
654 } 679 }
655 680
664 { 689 {
665 target += "Path,GET,POST,DELETE,PUT,Summary\n"; 690 target += "Path,GET,POST,DELETE,PUT,Summary\n";
666 for (Paths::const_iterator it = paths_.begin(); it != paths_.end(); ++it) 691 for (Paths::const_iterator it = paths_.begin(); it != paths_.end(); ++it)
667 { 692 {
668 target += "``" + it->first + "``,"; 693 target += "``" + it->first + "``,";
669 target += FormatUrl(openApiUrl, it->second.HasGet(), it->second.GetTag(), it->first, "get") + ","; 694 target += it->second.Format(openApiUrl, HttpMethod_Get, it->first) + ",";
670 target += FormatUrl(openApiUrl, it->second.HasPost(), it->second.GetTag(), it->first, "post") + ","; 695 target += it->second.Format(openApiUrl, HttpMethod_Post, it->first) + ",";
671 target += FormatUrl(openApiUrl, it->second.HasDelete(), it->second.GetTag(), it->first, "delete") + ","; 696 target += it->second.Format(openApiUrl, HttpMethod_Delete, it->first) + ",";
672 target += FormatUrl(openApiUrl, it->second.HasPut(), it->second.GetTag(), it->first, "put") + ","; 697 target += it->second.Format(openApiUrl, HttpMethod_Put, it->first) + ",";
673 target += it->second.GetSummary() + "\n"; 698 target += it->second.GetSummary() + "\n";
674 } 699 }
675 } 700 }
676 }; 701 };
677 } 702 }