TypeRegistry.h 16 KB

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