/* This file is part of MAUS: http://micewww.pp.rl.ac.uk/projects/maus * * MAUS is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * MAUS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MAUS. If not, see . */ #ifndef _SRC_COMMON_CPP_JSONCPPPROCESSORS_OBJECTPROCESSOR_INL_HH_ #define _SRC_COMMON_CPP_JSONCPPPROCESSORS_OBJECTPROCESSOR_INL_HH_ #include #include "src/common_cpp/Utils/JsonWrapper.hh" #include "src/common_cpp/JsonCppProcessors/Common/ObjectProcessorNS/BaseItem.hh" #include "src/common_cpp/JsonCppProcessors/Common/ObjectProcessorNS/PointerItem.hh" #include "src/common_cpp/JsonCppProcessors/Common/ObjectProcessorNS/ConstantItem.hh" #include "src/common_cpp/JsonCppProcessors/Common/ObjectProcessorNS/ValueItem.hh" #include "src/common_cpp/JsonCppProcessors/Common/ObjectProcessorNS/BaseClassItem.hh" #include "src/common_cpp/JsonCppProcessors/Common/ObjectProcessorNS/PointerRefItem.hh" #include "src/common_cpp/JsonCppProcessors/Common/ObjectProcessorNS/PointerTRefItem.hh" #include "src/common_cpp/JsonCppProcessors/Common/ObjectProcessorNS/PointerTRefArrayItem.hh" #include "src/common_cpp/JsonCppProcessors/Common/ObjectProcessorNS/IgnoreItem.hh" namespace MAUS { template ObjectProcessor::ObjectProcessor() : _throws_if_unknown_branches(true), _items() { } template template void ObjectProcessor::RegisterPointerBranch( std::string branch_name, ProcessorBase* child_processor, ChildType* (ObjectType::*GetMethod)() const, void (ObjectType::*SetMethod)(ChildType* value), bool is_required) { using ObjectProcessorNS::BaseItem; using ObjectProcessorNS::PointerItem; BaseItem* item = new PointerItem (branch_name, child_processor, GetMethod, SetMethod, is_required); _items[branch_name] = item; } template template void ObjectProcessor::RegisterPointerReference( std::string branch_name, ChildType* (ObjectType::*GetMethod)() const, void (ObjectType::*SetMethod)(ChildType* value), bool is_required) { using ObjectProcessorNS::BaseItem; using ObjectProcessorNS::PointerRefItem; BaseItem* item = new PointerRefItem (branch_name, GetMethod, SetMethod, is_required); _items[branch_name] = item; } template void ObjectProcessor::RegisterTRef( std::string branch_name, TObject* (ObjectType::*GetMethod)() const, void (ObjectType::*SetMethod)(TObject* value), bool is_required) { using ObjectProcessorNS::BaseItem; using ObjectProcessorNS::PointerTRefItem; BaseItem* item = new PointerTRefItem (branch_name, GetMethod, SetMethod, is_required); _items[branch_name] = item; } template void ObjectProcessor::RegisterTRefArray( std::string branch_name, TRefArrayProcessor* child_processor, TRefArray* (ObjectType::*GetMethod)() const, void (ObjectType::*SetMethod)(TRefArray* value), bool is_required) { using ObjectProcessorNS::BaseItem; using ObjectProcessorNS::PointerTRefArrayItem; BaseItem* item = new PointerTRefArrayItem (branch_name, child_processor, GetMethod, SetMethod, is_required); _items[branch_name] = item; } template template void ObjectProcessor::RegisterValueBranch( std::string branch_name, ProcessorBase* child_processor, ChildType (ObjectType::*GetMethod)() const, void (ObjectType::*SetMethod)(ChildType value), bool is_required) { using ObjectProcessorNS::BaseItem; using ObjectProcessorNS::ValueItem; BaseItem* item = new ValueItem (branch_name, child_processor, GetMethod, SetMethod, is_required); _items[branch_name] = item; } template template void ObjectProcessor::RegisterBaseClass( std::string branch_name, ProcessorBase* child_processor, void (ChildType::*SetMethod)(ChildType value), bool is_required) { using ObjectProcessorNS::BaseItem; using ObjectProcessorNS::BaseClassItem; BaseItem* item = new BaseClassItem (branch_name, child_processor, SetMethod, is_required); _items[branch_name] = item; } template void ObjectProcessor::RegisterConstantBranch( std::string branch_name, Json::Value child_value, bool is_required) { using ObjectProcessorNS::BaseItem; using ObjectProcessorNS::ConstantItem; BaseItem* item = new ConstantItem (branch_name, child_value, is_required); _items[branch_name] = item; } template void ObjectProcessor::RegisterIgnoredBranch( std::string branch_name, bool is_required) { using ObjectProcessorNS::BaseItem; using ObjectProcessorNS::IgnoreItem; BaseItem* item = new IgnoreItem (branch_name, is_required); _items[branch_name] = item; } template ObjectType* ObjectProcessor::JsonToCpp( const Json::Value& json_object) { if (json_object.type() != Json::objectValue) { std::string tp = JsonWrapper::ValueTypeToString(json_object.type()); throw(Exceptions::Exception(Exceptions::recoverable, "Attempt to pass a json "+tp+" type as an object", "ObjectProcessor::JsonToCpp")); } if (_throws_if_unknown_branches && HasUnknownBranches(json_object)) { Json::Value::Members members = json_object.getMemberNames(); std::string unknown = ""; for (Json::Value::Members::iterator it = members.begin(); it != members.end(); ++it) { if (_items.find(*it) == _items.end()) { unknown += *it+" "; } } throw(Exceptions::Exception(Exceptions::recoverable, "Failed to recognise all json properties "+unknown, "ObjectProcessor::JsonToCpp")); } ObjectType* cpp_object = new ObjectType(); for (my_iter it = _items.begin(); it != _items.end(); ++it) { try { it->second->SetCppChild(json_object, *cpp_object); } catch (Exceptions::Exception exc) { delete cpp_object; exc.SetMessage("In branch "+it->first+"\n" +exc.GetMessage()); throw exc; } } return cpp_object; } template Json::Value* ObjectProcessor::CppToJson (const ObjectType& cpp_object, std::string path) { Json::Value* json_object = new Json::Value(Json::objectValue); JsonWrapper::Path::SetPath(*json_object, path); for (my_iter it = _items.begin(); it != _items.end(); ++it) { try { it->second->SetJsonChild(cpp_object, *json_object); } catch (Exceptions::Exception exc) { delete json_object; exc.SetMessage("In branch "+it->first+"\n" +exc.GetMessage()); throw exc; } } return json_object; } template ObjectProcessor::~ObjectProcessor() { for (my_iter it = _items.begin(); it != _items.end(); ++it) { delete it->second; } } template bool ObjectProcessor::HasUnknownBranches (const Json::Value& value) const { if (!value.isObject()) { std::string tp = JsonWrapper::ValueTypeToString(value.type()); throw(Exceptions::Exception(Exceptions::recoverable, "Comparison value must be a json object type - found "+tp, "ObjectProcessor::HasUnknownBranches(...)")); } Json::Value::Members members = value.getMemberNames(); for (Json::Value::Members::iterator it = members.begin(); it != members.end(); ++it) { if (_items.find(*it) == _items.end()) { return true; } } return false; } template void ObjectProcessor::SetThrowsIfUnknownBranches(bool will_throw) { _throws_if_unknown_branches = will_throw; } template bool ObjectProcessor::GetThrowsIfUnknownBranches() const { return _throws_if_unknown_branches; } } // namespace MAUS #endif // #ifndef _SRC_COMMON_CPP_JSONCPPPROCESSORS_OBJECTPROCESSOR_INL_HH_