TypeRegistry.h 17 KB

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