TypeRegistry.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516
  1. #pragma once
  2. #include <Array.h>
  3. #include <DataValidator.h>
  4. #include <JSON.h>
  5. #include <Logging.h>
  6. #include <Trie.h>
  7. #include <typeinfo>
  8. class TypeRegistry;
  9. #define JSONObjectValidationBuilder \
  10. Framework::Validator::ObjectValidationBuilder< \
  11. Framework::Validator::DataValidator>
  12. template<typename T> class SimpleTypeFactory
  13. : public Framework::ReferenceCounter
  14. {
  15. public:
  16. SimpleTypeFactory()
  17. : ReferenceCounter() {};
  18. virtual T fromJson(Framework::JSON::JSONValue* zJson) const = 0;
  19. virtual Framework::JSON::JSONValue* toJson(T value) const = 0;
  20. virtual Framework::Validator::DataValidator* getValidator() const = 0;
  21. };
  22. /*
  23. * Used to convert an object of type T to a JSONValue and vice versa.
  24. * Can be registered at the TypeRegistry to be used by the JSON system
  25. */
  26. template<typename T> class ObjectTypeFactory : public SimpleTypeFactory<T*>
  27. {
  28. protected:
  29. mutable Framework::Validator::DataValidator* validator;
  30. mutable bool insideGetValidator;
  31. public:
  32. ObjectTypeFactory()
  33. : SimpleTypeFactory<T*>(),
  34. validator(0),
  35. insideGetValidator(false) {};
  36. ~ObjectTypeFactory()
  37. {
  38. if (validator)
  39. {
  40. validator->release();
  41. }
  42. }
  43. T* fromJson(Framework::JSON::JSONValue* zJson) const final override
  44. {
  45. return fromJson(zJson->asObject());
  46. }
  47. Framework::JSON::JSONValue* toJson(T* value) const final override
  48. {
  49. return toJsonObject(value);
  50. }
  51. virtual Framework::Validator::DataValidator* getValidator() const override
  52. {
  53. if (!this->validator)
  54. {
  55. if (!insideGetValidator)
  56. {
  57. insideGetValidator = true;
  58. this->validator = addToValidator(
  59. Framework::Validator::DataValidator::buildForObject())
  60. ->finishObject();
  61. insideGetValidator = false;
  62. }
  63. else
  64. {
  65. throw "recursive endless loop. a json object needs to contain "
  66. "itself";
  67. }
  68. }
  69. return dynamic_cast<Framework::Validator::DataValidator*>(
  70. this->validator->getThis());
  71. };
  72. virtual JSONObjectValidationBuilder* addToValidator(
  73. JSONObjectValidationBuilder* builder) const = 0;
  74. protected:
  75. virtual T* fromJson(Framework::JSON::JSONObject* zJson) const = 0;
  76. virtual Framework::JSON::JSONObject* toJsonObject(T* zObject) const = 0;
  77. };
  78. /*
  79. * Used to convert an object of type S witch inherits from type T to a
  80. * JSONValue and vice versa. Can be registered at the TypeRegistry to be
  81. * used by the JSON
  82. */
  83. template<typename T,
  84. typename S,
  85. typename = typename std::enable_if<std::is_base_of<T, S>::value>::type>
  86. class SubTypeFactory : public ObjectTypeFactory<S>
  87. {
  88. public:
  89. SubTypeFactory()
  90. : ObjectTypeFactory<S>() {};
  91. virtual Framework::Validator::DataValidator*
  92. getValidator() const final override
  93. {
  94. if (!this->validator)
  95. {
  96. Framework::Text referenceId = "_type_";
  97. referenceId.append() << typeid(T).name() << "_" << getTypeToken();
  98. if (!this->insideGetValidator)
  99. {
  100. this->insideGetValidator = true;
  101. auto result = this->addToValidator(
  102. Framework::Validator::DataValidator::
  103. buildForObject()
  104. ->withRequiredString("type")
  105. ->withExactMatch(getTypeToken())
  106. ->finishString()
  107. ->setReferenceId(referenceId))
  108. ->finishObject();
  109. if (this->validator)
  110. {
  111. // during a recursive call the validator could have ben
  112. // initialized to a reference validator (else branch below)
  113. this->validator->release();
  114. }
  115. this->validator = result;
  116. this->insideGetValidator = false;
  117. }
  118. else
  119. {
  120. this->validator
  121. = Framework::Validator::DataValidator::buildForReference(
  122. referenceId);
  123. }
  124. }
  125. return dynamic_cast<Framework::Validator::DataValidator*>(
  126. this->validator->getThis());
  127. };
  128. virtual const char* getTypeToken() const = 0;
  129. virtual const char* getTypeName() const
  130. {
  131. return typeid(S).name();
  132. }
  133. };
  134. template<typename T> class SubTypeFactoryRef
  135. : public Framework::ReferenceCounter
  136. {
  137. private:
  138. std::function<const char*()> typetokenFunc;
  139. std::function<T*(Framework::JSON::JSONValue*)> fromJsonFunc;
  140. std::function<Framework::JSON::JSONValue*(T*)> toJsonFunc;
  141. std::function<Framework::Validator::DataValidator*()> getValidatorFunc;
  142. Framework::ReferenceCounter* factory;
  143. public:
  144. SubTypeFactoryRef(std::function<const char*()> typetokenFunc,
  145. std::function<T*(Framework::JSON::JSONValue*)> fromJsonFunc,
  146. std::function<Framework::JSON::JSONValue*(T*)> toJsonFunc,
  147. std::function<Framework::Validator::DataValidator*()> getValidatorFunc,
  148. Framework::ReferenceCounter* factory)
  149. : ReferenceCounter(),
  150. typetokenFunc(typetokenFunc),
  151. fromJsonFunc(fromJsonFunc),
  152. toJsonFunc(toJsonFunc),
  153. getValidatorFunc(getValidatorFunc),
  154. factory(factory)
  155. {}
  156. ~SubTypeFactoryRef()
  157. {
  158. factory->release();
  159. }
  160. T* fromJson(Framework::JSON::JSONValue* zJson) const
  161. {
  162. return fromJsonFunc(zJson);
  163. }
  164. Framework::JSON::JSONValue* toJson(T* zObject) const
  165. {
  166. return toJsonFunc(zObject);
  167. }
  168. Framework::Validator::DataValidator* getValidator() const
  169. {
  170. return getValidatorFunc();
  171. }
  172. const char* getTypeToken() const
  173. {
  174. return typetokenFunc();
  175. }
  176. };
  177. template<typename T> class PolymorphTypeFactory : public ObjectTypeFactory<T>
  178. {
  179. private:
  180. Framework::RCArray<SubTypeFactoryRef<T>> factories;
  181. Framework::RCArray<Framework::Text> typeNames;
  182. public:
  183. PolymorphTypeFactory()
  184. : ObjectTypeFactory<T>()
  185. {}
  186. T* fromJson(Framework::JSON::JSONObject* zJson) const override
  187. {
  188. for (SubTypeFactoryRef<T>* factory : factories)
  189. {
  190. if (zJson->zValue("type")->asString()->getString().isEqual(
  191. factory->getTypeToken()))
  192. {
  193. return factory->fromJson(zJson);
  194. }
  195. }
  196. Framework::Logging::error()
  197. << "No Sub Type Factory for typetoken "
  198. << zJson->zValue("type")->asString()->getString() << " of type "
  199. << typeid(T).name() << " was found.";
  200. return 0;
  201. }
  202. Framework::JSON::JSONObject* toJsonObject(T* zObject) const override
  203. {
  204. auto name = typeNames.begin();
  205. for (SubTypeFactoryRef<T>* factory : factories)
  206. {
  207. if (name->isEqual(typeid(*zObject).name()))
  208. {
  209. Framework::JSON::JSONObject* result
  210. = factory->toJson(zObject)->asObject();
  211. result->addValue("type",
  212. new Framework::JSON::JSONString(factory->getTypeToken()));
  213. return result;
  214. }
  215. name++;
  216. }
  217. Framework::Logging::error()
  218. << "No Sub Type Factory for subtype " << typeid(*zObject).name()
  219. << " of type " << typeid(T).name() << " was found.";
  220. return new Framework::JSON::JSONObject();
  221. }
  222. JSONObjectValidationBuilder* addToValidator(
  223. JSONObjectValidationBuilder* builder) const override
  224. {
  225. Framework::Logging::error()
  226. << "Can not add polymorph json validator to an object "
  227. "validation builder";
  228. throw "Can not add polymorph json "
  229. "validator to an object "
  230. "validation builder";
  231. }
  232. Framework::Validator::DataValidator* getValidator() const override
  233. {
  234. if (!this->validator)
  235. {
  236. if (!this->insideGetValidator)
  237. {
  238. this->insideGetValidator = true;
  239. auto validator
  240. = Framework::Validator::DataValidator::buildForOneOf()
  241. ->typeSpecifiedByAttribute("type");
  242. for (SubTypeFactoryRef<T>* factory : factories)
  243. {
  244. validator
  245. = validator->addAcceptedType(factory->getValidator());
  246. }
  247. if (this->validator)
  248. {
  249. // during a recursive call the validator could have ben
  250. // initialized to a reference validator (else branch below)
  251. this->validator->release();
  252. }
  253. this->validator = validator->finishOneOf();
  254. this->insideGetValidator = false;
  255. }
  256. else
  257. {
  258. auto validator
  259. = Framework::Validator::DataValidator::buildForOneOf()
  260. ->typeSpecifiedByAttribute("type");
  261. for (SubTypeFactoryRef<T>* factory : factories)
  262. {
  263. validator = validator->addAcceptedType(
  264. Framework::Validator::DataValidator::buildForReference(
  265. ((Framework::Text("_type_") += typeid(T).name())
  266. += "_") += factory->getTypeToken()));
  267. }
  268. this->validator = validator->finishOneOf();
  269. }
  270. }
  271. return dynamic_cast<Framework::Validator::DataValidator*>(
  272. this->validator->getThis());
  273. }
  274. template<typename S> void addFactory(SubTypeFactory<T, S>* factory)
  275. {
  276. factories.add(new SubTypeFactoryRef<T>(
  277. [factory]() { return factory->getTypeToken(); },
  278. [factory](Framework::JSON::JSONValue* zJson) {
  279. S* value = factory->fromJson(zJson);
  280. if (value)
  281. {
  282. return dynamic_cast<T*>(value);
  283. }
  284. return (T*)0;
  285. },
  286. [factory](T* zObject) {
  287. return factory->toJson(dynamic_cast<S*>(zObject));
  288. },
  289. [factory]() { return factory->getValidator(); },
  290. dynamic_cast<Framework::ReferenceCounter*>(factory)));
  291. typeNames.add(new Framework::Text(factory->getTypeName()));
  292. }
  293. };
  294. class TypeFatoryRef : public Framework::ReferenceCounter
  295. {
  296. private:
  297. std::function<void*(Framework::JSON::JSONValue*)> fromJsonFunc;
  298. std::function<Framework::JSON::JSONValue*(void*)> toJsonFunc;
  299. std::function<Framework::Validator::DataValidator*()> getValidatorFunc;
  300. Framework::ReferenceCounter* factory;
  301. public:
  302. TypeFatoryRef(
  303. std::function<void*(Framework::JSON::JSONValue*)> fromJsonFunc,
  304. std::function<Framework::JSON::JSONValue*(void*)> toJsonFunc,
  305. std::function<Framework::Validator::DataValidator*()> getValidatorFunc,
  306. Framework::ReferenceCounter* factory)
  307. : ReferenceCounter(),
  308. fromJsonFunc(fromJsonFunc),
  309. toJsonFunc(toJsonFunc),
  310. getValidatorFunc(getValidatorFunc),
  311. factory(factory)
  312. {}
  313. ~TypeFatoryRef()
  314. {
  315. factory->release();
  316. }
  317. void* fromJson(Framework::JSON::JSONValue* zJson) const
  318. {
  319. return fromJsonFunc(zJson);
  320. }
  321. Framework::JSON::JSONValue* toJson(void* zObject) const
  322. {
  323. return toJsonFunc(zObject);
  324. }
  325. Framework::Validator::DataValidator* getValidator() const
  326. {
  327. return getValidatorFunc();
  328. }
  329. Framework::ReferenceCounter* zFactory() const
  330. {
  331. return factory;
  332. }
  333. };
  334. class TypeRegistry : public Framework::ReferenceCounter
  335. {
  336. private:
  337. Framework::RCTrie<TypeFatoryRef> parsableTypes;
  338. Framework::RCArray<Framework::Text> parsableTypeNames;
  339. public:
  340. TypeRegistry();
  341. template<typename T,
  342. typename S,
  343. typename = typename std::enable_if<std::is_base_of<T, S>::value>::type>
  344. void registerSubType(SubTypeFactory<T, S>* factory)
  345. {
  346. Framework::Text typeId = typeid(T).name();
  347. TypeFatoryRef* typeFactoryRef
  348. = parsableTypes.z(typeId, typeId.getLength());
  349. if (!typeFactoryRef)
  350. {
  351. PolymorphTypeFactory<T>* polymorphFactory
  352. = new PolymorphTypeFactory<T>();
  353. registerType(polymorphFactory);
  354. typeFactoryRef = parsableTypes.z(typeId, typeId.getLength());
  355. parsableTypeNames.add(new Framework::Text(typeId));
  356. }
  357. PolymorphTypeFactory<T>* polymorphFactory
  358. = dynamic_cast<PolymorphTypeFactory<T>*>(
  359. typeFactoryRef->zFactory());
  360. if (!polymorphFactory)
  361. {
  362. Framework::Logging::error()
  363. << Framework::Text("Type not registered as Polymorphic type: ")
  364. + typeId;
  365. throw Framework::Text("Type not registered as Polymorphic type: ")
  366. + typeId;
  367. }
  368. polymorphFactory->template addFactory<S>(
  369. dynamic_cast<SubTypeFactory<T, S>*>(factory->getThis()));
  370. Framework::Text typeIdS = typeid(S).name();
  371. parsableTypeNames.add(new Framework::Text(typeIdS));
  372. registerType(factory);
  373. }
  374. template<typename T> void registerType(ObjectTypeFactory<T>* factory)
  375. {
  376. registerType(typeid(T).name(), factory);
  377. }
  378. template<typename T>
  379. void registerType(Framework::Text typeId, SimpleTypeFactory<T>* factory)
  380. {
  381. TypeFatoryRef* typeFactoryRef
  382. = parsableTypes.z(typeId, typeId.getLength());
  383. if (typeFactoryRef)
  384. {
  385. Framework::Logging::error()
  386. << Framework::Text("Type already registered: ") + typeId;
  387. throw Framework::Text("Type already registered: ") + typeId;
  388. }
  389. typeFactoryRef = new TypeFatoryRef(
  390. [factory](Framework::JSON::JSONValue* zJson) {
  391. return (void*)factory->fromJson(zJson);
  392. },
  393. [factory](void* zObject) { return factory->toJson((T)zObject); },
  394. [factory]() { return factory->getValidator(); },
  395. factory);
  396. parsableTypes.set(typeId, typeId.getLength(), typeFactoryRef);
  397. parsableTypeNames.add(new Framework::Text(typeId));
  398. }
  399. template<typename T>
  400. T fromJson(Framework::Text typeId, Framework::JSON::JSONValue* zJson) const
  401. {
  402. TypeFatoryRef* typeFactoryRef
  403. = parsableTypes.z(typeId, typeId.getLength());
  404. if (!typeFactoryRef)
  405. {
  406. Framework::Logging::error()
  407. << Framework::Text("Type not registered: ") + typeId;
  408. throw Framework::Text("Type not registered: ") + typeId;
  409. }
  410. return (T)(typeFactoryRef->fromJson(zJson));
  411. }
  412. template<typename T> T* fromJson(Framework::JSON::JSONValue* zJson) const
  413. {
  414. return fromJson<T*>(typeid(T).name(), zJson);
  415. }
  416. template<typename T> Framework::JSON::JSONValue* toJson(T* zObject) const
  417. {
  418. return toJson<T*>(typeid(T).name(), zObject);
  419. }
  420. template<typename T> Framework::JSON::JSONValue* toJson(
  421. Framework::Text typeId, const T zObject) const
  422. {
  423. TypeFatoryRef* typeFactoryRef
  424. = parsableTypes.z(typeId, typeId.getLength());
  425. if (!typeFactoryRef)
  426. {
  427. Framework::Logging::error()
  428. << Framework::Text("Type not registered: ") + typeId;
  429. throw Framework::Text("Type not registered: ") + typeId;
  430. }
  431. return typeFactoryRef->toJson((void*)zObject);
  432. }
  433. template<typename T>
  434. Framework::Validator::DataValidator* getValidator() const
  435. {
  436. return getValidator<T>(typeid(T).name());
  437. }
  438. template<typename T> Framework::Validator::DataValidator* getValidator(
  439. Framework::Text typeId) const
  440. {
  441. TypeFatoryRef* typeFactoryRef
  442. = parsableTypes.z(typeId, typeId.getLength());
  443. if (!typeFactoryRef)
  444. {
  445. Framework::Logging::error()
  446. << Framework::Text("Type not registered: ") + typeId;
  447. throw Framework::Text("Type not registered: ") + typeId;
  448. }
  449. return typeFactoryRef->getValidator();
  450. }
  451. template<typename T> Framework::JSON::JSONValue* getValidParts(
  452. Framework::JSON::JSONValue* zJson) const
  453. {
  454. Framework::RCArray<Framework::Validator::ValidationResult> invalidParts;
  455. Framework::Validator::DataValidator* validator = getValidator<T>();
  456. Framework::JSON::JSONValue* result
  457. = validator->getValidParts(zJson, &invalidParts);
  458. for (Framework::Validator::ValidationResult* invalidPart : invalidParts)
  459. {
  460. Framework::Logging::error() << invalidPart->getInvalidInfo();
  461. }
  462. validator->release();
  463. return result;
  464. }
  465. void writeSyntaxInfo(Framework::Text folderPath) const;
  466. };