610{
611
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 }
618 }
619
620
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
640 }
641 }
642
643
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"));
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
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
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
699 }
700
701
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
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
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"));
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
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}