TypeRegistry.h 14 KB

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