Smithy Qt 0.1.0-pre
Internal development documentation
Loading...
Searching...
No Matches
ShapePrivate Class Reference

The ShapePrivate class provides private implementation for Shape. More...

Collaboration diagram for ShapePrivate:
[legend]

Public Member Functions

 ShapePrivate (Shape *const q)
 

Static Public Member Functions

static Shape::Type getType (const QJsonObject &ast)
 
static Shape::Type getType (const QString &type)
 
static Shape::Member getMember (const QJsonObject &ast, const QString &name)
 
static ShapeIdStringMap getShapeIdStrMap (const QJsonObject &ast, const QString &name)
 
static Shape::ShapeReference getShapeRef (const QJsonObject &ast, const QString &name)
 
static Shape::ShapeReferences getShapeRefs (const QJsonObject &ast, const QString &name)
 
static Shape::StringMemberMap getStrMemberMap (const QJsonObject &ast, const QString &name)
 
static Shape::StringShapeRefMap getStrShapeRefMap (const QJsonObject &ast, const QString &name)
 
static Shape::TraitsMap getTraitsMap (const QJsonObject &ast, const QString &name)
 
static QString getString (const QJsonObject &ast, const QString &name)
 
static QStringList supportedProperties (const Shape::Type &type)
 
static QStringList requiredProperties (const Shape::Type &type)
 
static bool validateIdentifier (const QString &id)
 
static bool validateProperty (const QString &name, const QJsonValue &value)
 

Static Protected Member Functions

static Q_LOGGING_CATEGORY (lc, "smithy.Shape", QtInfoMsg)
 Logging category for Shape.
 

Protected Attributes

Shapeq_ptr
 Internal q-pointer.
 

Private Member Functions

 Q_DECLARE_TR_FUNCTIONS (Shape)
 

Private Attributes

QJsonObject ast
 
Shape::Error error
 
ShapeId id
 
Shape::Type type
 

Detailed Description

The ShapePrivate class provides private implementation for Shape.

Definition at line 19 of file shape_p.h.

Constructor & Destructor Documentation

◆ ShapePrivate()

ShapePrivate::ShapePrivate ( Shape *const q)
explicit

Constructs a new ShapePrivate object with public implementation q.

Definition at line 309 of file shape.cpp.

309 : q_ptr(q)
310{
311
312}
Shape * q_ptr
Internal q-pointer.
Definition shape_p.h:45

References q_ptr.

Member Function Documentation

◆ getMember()

Shape::Member ShapePrivate::getMember ( const QJsonObject & ast,
const QString & name )
static

Definition at line 367 of file shape.cpp.

368{
369 Shape::Member member;
370 Q_UNUSED(ast);
371 Q_UNUSED(name);
372 Q_UNIMPLEMENTED();
373 return member;
374}

◆ getShapeIdStrMap()

ShapeIdStringMap ShapePrivate::getShapeIdStrMap ( const QJsonObject & ast,
const QString & name )
static

Definition at line 376 of file shape.cpp.

377{
378 ShapeIdStringMap shapeIdMap;
379 Q_UNUSED(ast);
380 Q_UNUSED(name);
381 Q_UNIMPLEMENTED();
382 return shapeIdMap;
383}

◆ getShapeRef()

Shape::ShapeReference ShapePrivate::getShapeRef ( const QJsonObject & ast,
const QString & name )
static

Definition at line 385 of file shape.cpp.

386{
387 const auto iter = ast.constFind(name);
388 if (iter == ast.constEnd()) {
389 return Shape::ShapeReference{};
390 }
391 const QJsonObject shapeRefObj = iter->toObject();
392 return Shape::ShapeReference{ shapeRefObj.value(QLatin1String("target")).toString() };
393}

◆ getShapeRefs()

Shape::ShapeReferences ShapePrivate::getShapeRefs ( const QJsonObject & ast,
const QString & name )
static

Definition at line 395 of file shape.cpp.

396{
397 const auto iter = ast.constFind(name);
398 if (iter == ast.constEnd()) {
399 return Shape::ShapeReferences{};
400 }
401 const QJsonArray shapeRefsArray = iter->toArray();
402 Shape::ShapeReferences shapeRefs;
403 for (const QJsonValue &shapeRef: shapeRefsArray) {
404 shapeRefs.insert(Shape::ShapeReference{
405 shapeRef.toObject().value(QLatin1String("target")).toString()
406 });
407 }
408 return shapeRefs;
409}

◆ getString()

QString ShapePrivate::getString ( const QJsonObject & ast,
const QString & name )
static

Definition at line 439 of file shape.cpp.

440{
441 const auto iter = ast.constFind(name);
442 return (iter == ast.constEnd()) ? QString() : iter->toString();
443}

◆ getStrMemberMap()

Shape::StringMemberMap ShapePrivate::getStrMemberMap ( const QJsonObject & ast,
const QString & name )
static

Definition at line 411 of file shape.cpp.

412{
413 Shape::StringMemberMap memberMap;
414 Q_UNUSED(ast);
415 Q_UNUSED(name);
416 Q_UNIMPLEMENTED();
417 return memberMap;
418}

◆ getStrShapeRefMap()

Shape::StringShapeRefMap ShapePrivate::getStrShapeRefMap ( const QJsonObject & ast,
const QString & name )
static

Definition at line 420 of file shape.cpp.

421{
422 Shape::StringShapeRefMap shapeRefMap;
423 Q_UNUSED(ast);
424 Q_UNUSED(name);
425 Q_UNIMPLEMENTED();
426 return shapeRefMap;
427}

◆ getTraitsMap()

Shape::TraitsMap ShapePrivate::getTraitsMap ( const QJsonObject & ast,
const QString & name )
static

Definition at line 429 of file shape.cpp.

430{
431 Shape::TraitsMap traitsMap;
432 const QJsonObject traits = ast.value(name).toObject();
433 for (auto iter = traits.constBegin(); iter != traits.constEnd(); ++iter) {
434 traitsMap.insert(iter.key(), iter.value());
435 }
436 return traitsMap;
437}

◆ getType() [1/2]

Shape::Type ShapePrivate::getType ( const QJsonObject & ast)
static

Definition at line 314 of file shape.cpp.

315{
316 const QJsonValue value = ast.value(QLatin1String("type"));
317 if (value.isUndefined()) {
318 qCCritical(lc).noquote() << tr("Shape has no type property");
320 }
321 if (value.type() != QJsonValue::String) {
322 qCCritical(lc).noquote() << tr("Shape type property is not a JSON string:") << value;
324 }
325 return getType(value.toString());
326}
@ Undefined
The shape is undefined, usually the result of an error condition.
Definition shape.h:38

◆ getType() [2/2]

Shape::Type ShapePrivate::getType ( const QString & type)
static

Definition at line 328 of file shape.cpp.

329{
330 // Simple Types
331 if (type == QLatin1String("blob")) return Shape::Type::Blob;
332 if (type == QLatin1String("boolean")) return Shape::Type::Boolean;
333 if (type == QLatin1String("string")) return Shape::Type::String;
334 if (type == QLatin1String("enum")) return Shape::Type::Enum;
335 if (type == QLatin1String("byte")) return Shape::Type::Byte;
336 if (type == QLatin1String("short")) return Shape::Type::Short;
337 if (type == QLatin1String("integer")) return Shape::Type::Integer;
338 if (type == QLatin1String("intEnum")) return Shape::Type::IntEnum;
339 if (type == QLatin1String("long")) return Shape::Type::Long;
340 if (type == QLatin1String("float")) return Shape::Type::Float;
341 if (type == QLatin1String("double")) return Shape::Type::Double;
342 if (type == QLatin1String("bigInteger")) return Shape::Type::BigInteger;
343 if (type == QLatin1String("bigDecimal")) return Shape::Type::BigDecimal;
344 if (type == QLatin1String("timestamp")) return Shape::Type::Timestamp;
345 if (type == QLatin1String("document")) return Shape::Type::Document;
346
347 // Aggregate Types
348 if (type == QLatin1String("list")) return Shape::Type::List;
349 if (type == QLatin1String("set")) return Shape::Type::Set;
350 if (type == QLatin1String("map")) return Shape::Type::Map;
351 if (type == QLatin1String("structure")) return Shape::Type::Structure;
352 if (type == QLatin1String("union")) return Shape::Type::Union;
353
354
355 // Service Types
356 if (type == QLatin1String("service")) return Shape::Type::Service;
357 if (type == QLatin1String("operation")) return Shape::Type::Operation;
358 if (type == QLatin1String("resource")) return Shape::Type::Resource;
359
360 // Special Types
361 if (type == QLatin1String("apply")) return Shape::Type::Apply;
362
363 qCWarning(lc).noquote() << tr("Unknown shape type: %1").arg(type);
365}
@ IntEnum
An integer with a fixed set of values.
Definition shape.h:48
@ Document
Open content that functions as a kind of "any" type.
Definition shape.h:55
@ Float
Single precision IEEE-754 floating point number.
Definition shape.h:50
@ String
UTF-8 encoded string.
Definition shape.h:43
@ Boolean
Boolean value type.
Definition shape.h:42
@ Operation
Represents the input, output, and errors of an API operation.
Definition shape.h:67
@ Short
16-bit signed integer ranging from -32,768 to 32,767 (inclusive).
Definition shape.h:46
@ Map
Map data structure that maps string keys to homogeneous values.
Definition shape.h:60
@ List
Ordered collection of homogeneous values.
Definition shape.h:58
@ Set
Deprecated; use a list with the uniqueItems trait instead.
Definition shape.h:59
@ Long
64-bit signed integer ranging from -2^63 to (2^63)-1 (inclusive).
Definition shape.h:49
@ Apply
Traits to be applied to shapes outside of their definition.
Definition shape.h:71
@ Integer
32-bit signed integer ranging from -2^31 to (2^31)-1 (inclusive).
Definition shape.h:47
@ Byte
8-bit signed integer ranging from -128 to 127 (inclusive).
Definition shape.h:45
@ Timestamp
An instant in time with no UTC offset or timezone.
Definition shape.h:54
@ Resource
Entity with an identity that has a set of operations.
Definition shape.h:68
@ Service
Entry point of an API that aggregates resources and operations together.
Definition shape.h:66
@ Enum
A string with a fixed set of values.
Definition shape.h:44
@ BigInteger
Arbitrarily large signed integer.
Definition shape.h:52
@ Double
Double precision IEEE-754 floating point number.
Definition shape.h:51
@ Structure
Fixed set of named heterogeneous members.
Definition shape.h:61
@ Blob
Uninterpreted binary data.
Definition shape.h:41
@ BigDecimal
Arbitrary precision signed decimal number.
Definition shape.h:53

◆ requiredProperties()

QStringList ShapePrivate::requiredProperties ( const Shape::Type & type)
static

Definition at line 555 of file shape.cpp.

556{
557 switch (type) {
559 //case Shape::Type::Set: <- Set is synonym for List.
560 return QStringList{
561 QLatin1String("type"),
562 QLatin1String("member"),
563 };
564 break;
565
566 case Shape::Type::Map:
567 return QStringList{
568 QLatin1String("type"),
569 QLatin1String("key"),
570 QLatin1String("value"),
571 };
572 break;
573
577 return QStringList{
578 QLatin1String("type"),
579 QLatin1String("members"),
580 };
581
583 return QStringList{
584 QLatin1String("type"),
585 QLatin1String("version"),
586 };
587
589 return QStringList{
590 QLatin1String("type"),
591 QLatin1String("traits"),
592 };
593 break;
594
595 default:
596 return QStringList{
597 QLatin1String("type"),
598 };
599 }
600}

◆ supportedProperties()

QStringList ShapePrivate::supportedProperties ( const Shape::Type & type)
static

Definition at line 445 of file shape.cpp.

446{
447 switch (type) {
449 return QStringList{};
450
451 // Simple Types:
455 //case Shape::Type::Enum: <- Same as strucutre and union below.
459 //case Shape::Type::IntEnum: <- Same as strucutre and union below.
467 return QStringList{
468 QLatin1String("type"),
469 QLatin1String("traits"),
470 QLatin1String("mixins"),
471 };
472 break;
473
474 // Aggregate Types
476 //case Shape::Type::Set: <- Set is synonym for List.
477 return QStringList{
478 QLatin1String("type"),
479 QLatin1String("traits"),
480 QLatin1String("member"),
481 QLatin1String("mixins"),
482 };
483 break;
484 case Shape::Type::Map:
485 return QStringList{
486 QLatin1String("type"),
487 QLatin1String("traits"),
488 QLatin1String("key"),
489 QLatin1String("value"),
490 QLatin1String("mixins"),
491 };
492 break;
497 return QStringList{
498 QLatin1String("type"),
499 QLatin1String("traits"),
500 QLatin1String("members"),
501 QLatin1String("mixins"),
502 };
503
504 // Service Types
506 return QStringList{
507 QLatin1String("type"),
508 QLatin1String("traits"),
509 QLatin1String("version"),
510 QLatin1String("operations"),
511 QLatin1String("resources"),
512 QLatin1String("errors"),
513 QLatin1String("rename"),
514 QLatin1String("mixins"),
515 };
517 return QStringList{
518 QLatin1String("type"),
519 QLatin1String("traits"),
520 QLatin1String("input"),
521 QLatin1String("output"),
522 QLatin1String("errors"),
523 QLatin1String("mixins"),
524 };
526 return QStringList{
527 QLatin1String("type"),
528 QLatin1String("traits"),
529 QLatin1String("identifiers"),
530 QLatin1String("properties"),
531 QLatin1String("create"),
532 QLatin1String("put"),
533 QLatin1String("read"),
534 QLatin1String("update"),
535 QLatin1String("delete"),
536 QLatin1String("list"),
537 QLatin1String("operations"),
538 QLatin1String("collectionOperations"),
539 QLatin1String("resources"),
540 QLatin1String("mixins"),
541 };
542
543 // Special Types
545 return QStringList{
546 QLatin1String("type"),
547 QLatin1String("traits"),
548 };
549 break;
550 }
551 qCWarning(lc).noquote() << tr("Unknown shape type: 0x%1").arg((int)type, 0, 16);
552 return QStringList{};
553}

◆ validateIdentifier()

bool ShapePrivate::validateIdentifier ( const QString & id)
static

Definition at line 602 of file shape.cpp.

603{
604 // Lazily relying on the fact that ShapeId will validate the idenitifer regex pattern for now.
605 const ShapeId shapeId(id);
606 return ((shapeId.isValid()) && (!shapeId.hasNameSpace()) && (!shapeId.hasMemberName()));
607}

◆ validateProperty()

bool ShapePrivate::validateProperty ( const QString & name,
const QJsonValue & value )
static

Definition at line 609 of file shape.cpp.

610{
611 // Type string
612 if (name == QLatin1String("type")) {
613 if (!value.isString()) {
614 qCCritical(lc).noquote() << tr("%1 property is not a JSON string").arg(name);
615 return false;
616 }
617 return (getType(value.toString()) != Shape::Type::Undefined);
618 }
619
620 // TraitsMap
621 else if (name == QLatin1String("traits")) {
622 if (!value.isObject()) {
623 qCCritical(lc).noquote() << tr("%1 property is not a JSON object").arg(name);
624 return false;
625 }
626 const QJsonObject traits = value.toObject();
627 for (auto iter = traits.constBegin(); iter != traits.constEnd(); ++iter) {
628 const ShapeId id(iter.key());
629 if (!id.isValid()) {
630 qCCritical(lc).noquote() << tr("%1 property has trait with invalid shape ID %2")
631 .arg(name, iter.key());
632 return false;
633 }
634 if (id.isRelativeShapeId()) {
635 qCCritical(lc).noquote() << tr("%1 property has trait with relative shape ID %2")
636 .arg(name, iter.key());
637 return false;
638 }
639 // It doesn't matter (at this point) what type iter->value() is.
640 }
641 }
642
643 // Member (aka ShapeReference plus optional TraitsMap)
644 else if ((name == QLatin1String("member")) ||
645 (name == QLatin1String("key")) ||
646 (name == QLatin1String("value")))
647 {
648 if (!value.isObject()) {
649 qCCritical(lc).noquote() << tr("%1 property is not a JSON object").arg(name);
650 return false;
651 }
652 if (!validateProperty(QStringLiteral("ShapeReference"), value)) {
653 qCCritical(lc).noquote() << tr("%1 property is not valid ShapeReference").arg(name);
654 return false;
655 }
656 const QJsonObject member = value.toObject();
657 const auto traits = member.constFind(QLatin1String("traits")); // Optional.
658 if ((traits != member.constEnd()) && (!validateProperty(traits.key(), traits.value()))) {
659 qCCritical(lc).noquote() << tr("%1 property has invalid traits property").arg(name);
660 return false;
661 }
662 }
663
664 // Members (ie Set of Member instances)
665 else if (name == QLatin1String("members")) {
666 if (!value.isObject()) {
667 qCCritical(lc).noquote() << tr("%1 property is not a JSON object").arg(name);
668 return false;
669 }
670 QStringList names;
671 const QJsonObject members = value.toObject();
672 for (auto iter = members.constBegin(); iter != members.constEnd(); ++iter) {
673 if (!validateIdentifier(iter.key())) {
674 qCCritical(lc).noquote() << tr("%1 property has invalid member name %2")
675 .arg(name, iter.key());
676 return false;
677 }
678 if (names.contains(iter.key().toLower())) {
679 qCCritical(lc).noquote() << tr("%1 property has non-unique member name %2")
680 .arg(name, iter.key().toLower());
681 return false;
682 }
683 names.append(iter.key().toLower());
684 if (!validateProperty(QLatin1String("member"), iter.value())) {
685 qCCritical(lc).noquote() << tr("%1 property has invalid value for %2 property")
686 .arg(name, iter.key());
687 return false;
688 }
689 }
690 }
691
692 // Plain string
693 else if (name == QLatin1String("version")) {
694 if (!value.isString()) {
695 qCCritical(lc).noquote() << tr("%1 property is not a JSON string").arg(name);
696 return false;
697 }
698 // No further validation required; the string is free-form.
699 }
700
701 // ShapeReferences
702 else if ((name == QLatin1String("operations")) ||
703 (name == QLatin1String("collectionOperations")) ||
704 (name == QLatin1String("resources")) ||
705 (name == QLatin1String("errors")) ||
706 (name == QLatin1String("mixins"))) {
707 if (!value.isArray()) {
708 qCCritical(lc).noquote() << tr("%1 property is not a JSON array").arg(name);
709 return false;
710 }
711 const QJsonArray shapeRefs = value.toArray();
712 for (const QJsonValue &shapeRef: shapeRefs) {
713 if (!validateProperty(QLatin1String("ShapeReference"), shapeRef)) {
714 qCCritical(lc).noquote() << tr("%1 property has invalid entry").arg(name);
715 }
716 }
717 }
718
719 // ShapeIdStringMap
720 else if (name == QLatin1String("rename")) {
721 if (!value.isObject()) {
722 qCCritical(lc).noquote() << tr("%1 property is not a JSON object").arg(name);
723 return false;
724 }
725 const QJsonObject rename = value.toObject();
726 for (auto iter = rename.constBegin(); iter != rename.constEnd(); ++iter) {
727 const ShapeId shapeId(iter.key());
728 if (!shapeId.isValid()) {
729 qCCritical(lc).noquote() << tr("%1 property has invalid shape ID %2")
730 .arg(name, iter.key());
731 return false;
732 }
733 if (!iter.value().isString()) {
734 qCCritical(lc).noquote() << tr("%1 property has shape ID %2 with invalid value")
735 .arg(name, iter.key());
736 return false;
737 }
738 const QString indentifier = iter.value().toString();
739 if (validateIdentifier(indentifier)) {
740 qCCritical(lc).noquote() << tr("%1 property has shape ID %2 with invalid identifier %3")
741 .arg(name, iter.key(), indentifier);
742 return false;
743 }
744 }
745 }
746
747 // ShapeReference
748 else if ((name == QLatin1String("ShapeReference")) ||
749 (name == QLatin1String("create")) ||
750 (name == QLatin1String("put")) ||
751 (name == QLatin1String("read")) ||
752 (name == QLatin1String("update")) ||
753 (name == QLatin1String("delete")) ||
754 (name == QLatin1String("list")) ||
755 (name == QLatin1String("input")) ||
756 (name == QLatin1String("output"))) {
757 if (!value.isObject()) {
758 qCCritical(lc).noquote() << tr("%1 property is not a JSON object").arg(name);
759 return false;
760 }
761 const QJsonObject shapeRef = value.toObject();
762 const auto target = shapeRef.constFind(QLatin1String("target")); // Required.
763 if (target == shapeRef.constEnd()) {
764 qCCritical(lc).noquote() << tr("%1 property has no target property").arg(name);
765 return false;
766 }
767 if (!target.value().isString()) {
768 qCCritical(lc).noquote() << tr("%1 property has target value that not a JSON string")
769 .arg(name);
770 return false;
771 }
772 const QString shapeIdString = target.value().toString();
773 const ShapeId shapeId(shapeIdString);
774 if (!shapeId.isValid()) {
775 qCCritical(lc).noquote() << tr("%1 property has target with invalid shape ID %2")
776 .arg(name, shapeIdString);
777 return false;
778 }
779 if (shapeId.isRelativeShapeId()) {
780 qCCritical(lc).noquote() << tr("%1 property has target with relative shape ID %2")
781 .arg(name, shapeIdString);
782 return false;
783 }
784 }
785
786 // StringShapeRefMap
787 else if ((name == QLatin1String("identifiers")) ||
788 (name == QLatin1String("properties"))) {
789 if (!value.isObject()) {
790 qCCritical(lc).noquote() << tr("%1 property is not a JSON object").arg(name);
791 return false;
792 }
793 const QJsonObject identifiers = value.toObject();
794 for (auto iter = identifiers.constBegin(); iter != identifiers.constEnd(); ++iter) {
795 if (!validateIdentifier(iter.key())) {
796 qCCritical(lc).noquote() << tr("%1 property has invalid member name %2")
797 .arg(name, iter.key());
798 return false;
799 }
800 if (!validateProperty(QLatin1String("ShapeReference"), iter.value())) {
801 qCCritical(lc).noquote() << tr("%1 property has invalid value for %2 property")
802 .arg(name, iter.key());
803 return false;
804 }
805 }
806 }
807
808 else {
809 qCWarning(lc).noquote() << tr("Validation of %1 property not yet implemented").arg(name);
810 return false;
811 }
812 return true;
813}

Member Data Documentation

◆ ast

QJsonObject ShapePrivate::ast
private

Definition at line 49 of file shape_p.h.

◆ error

Shape::Error ShapePrivate::error
private

Definition at line 50 of file shape_p.h.

◆ id

ShapeId ShapePrivate::id
private

Definition at line 51 of file shape_p.h.

◆ q_ptr

Shape* ShapePrivate::q_ptr
protected

Internal q-pointer.

Definition at line 45 of file shape_p.h.

Referenced by ShapePrivate().

◆ type

Shape::Type ShapePrivate::type
private

Definition at line 52 of file shape_p.h.


The documentation for this class was generated from the following files: