Mercurial > hg > orthanc
comparison Core/JobsEngine/SetOfInstancesJob.cpp @ 2860:8b00e4cb4a6b
SetOfCommandsJob
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 05 Oct 2018 16:07:34 +0200 |
parents | ff0ed5ea9e4e |
children | 4e43e67f8ecf |
comparison
equal
deleted
inserted
replaced
2859:dedc2befbf41 | 2860:8b00e4cb4a6b |
---|---|
35 #include "SetOfInstancesJob.h" | 35 #include "SetOfInstancesJob.h" |
36 | 36 |
37 #include "../OrthancException.h" | 37 #include "../OrthancException.h" |
38 #include "../SerializationToolbox.h" | 38 #include "../SerializationToolbox.h" |
39 | 39 |
40 #include <cassert> | |
41 | |
40 namespace Orthanc | 42 namespace Orthanc |
41 { | 43 { |
42 SetOfInstancesJob::SetOfInstancesJob(bool hasTrailingStep) : | 44 class SetOfInstancesJob::InstanceCommand : public SetOfInstancesJob::ICommand |
43 hasTrailingStep_(hasTrailingStep), | 45 { |
44 started_(false), | 46 private: |
45 permissive_(false), | 47 SetOfInstancesJob& that_; |
46 position_(0) | 48 std::string instance_; |
47 { | 49 |
48 } | 50 public: |
49 | 51 InstanceCommand(SetOfInstancesJob& that, |
52 const std::string& instance) : | |
53 that_(that), | |
54 instance_(instance) | |
55 { | |
56 } | |
57 | |
58 const std::string& GetInstance() const | |
59 { | |
60 return instance_; | |
61 } | |
62 | |
63 virtual bool Execute() | |
64 { | |
65 if (!that_.HandleInstance(instance_)) | |
66 { | |
67 that_.failedInstances_.insert(instance_); | |
68 return false; | |
69 } | |
70 else | |
71 { | |
72 return true; | |
73 } | |
74 } | |
75 | |
76 virtual void Serialize(Json::Value& target) const | |
77 { | |
78 target = instance_; | |
79 } | |
80 }; | |
81 | |
82 | |
83 class SetOfInstancesJob::TrailingStepCommand : public SetOfInstancesJob::ICommand | |
84 { | |
85 private: | |
86 SetOfInstancesJob& that_; | |
87 | |
88 public: | |
89 TrailingStepCommand(SetOfInstancesJob& that) : | |
90 that_(that) | |
91 { | |
92 } | |
93 | |
94 virtual bool Execute() | |
95 { | |
96 return that_.HandleTrailingStep(); | |
97 } | |
98 | |
99 virtual void Serialize(Json::Value& target) const | |
100 { | |
101 target = Json::nullValue; | |
102 } | |
103 }; | |
104 | |
105 | |
106 class SetOfInstancesJob::InstanceUnserializer : | |
107 public SetOfInstancesJob::ICommandUnserializer | |
108 { | |
109 private: | |
110 SetOfInstancesJob& that_; | |
111 | |
112 public: | |
113 InstanceUnserializer(SetOfInstancesJob& that) : | |
114 that_(that) | |
115 { | |
116 } | |
117 | |
118 virtual ICommand* Unserialize(const Json::Value& source) const | |
119 { | |
120 if (source.type() == Json::nullValue) | |
121 { | |
122 return new TrailingStepCommand(that_); | |
123 } | |
124 else if (source.type() == Json::stringValue) | |
125 { | |
126 return new InstanceCommand(that_, source.asString()); | |
127 } | |
128 else | |
129 { | |
130 throw OrthancException(ErrorCode_BadFileFormat); | |
131 } | |
132 } | |
133 }; | |
50 | 134 |
51 void SetOfInstancesJob::Reserve(size_t size) | 135 |
52 { | 136 SetOfInstancesJob::SetOfInstancesJob() : |
53 if (started_) | 137 hasTrailingStep_(false) |
54 { | 138 { |
55 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
56 } | |
57 else | |
58 { | |
59 instances_.reserve(size); | |
60 } | |
61 } | 139 } |
62 | 140 |
63 | 141 |
64 size_t SetOfInstancesJob::GetStepsCount() const | |
65 { | |
66 if (HasTrailingStep()) | |
67 { | |
68 return instances_.size() + 1; | |
69 } | |
70 else | |
71 { | |
72 return instances_.size(); | |
73 } | |
74 } | |
75 | |
76 | |
77 void SetOfInstancesJob::AddInstance(const std::string& instance) | 142 void SetOfInstancesJob::AddInstance(const std::string& instance) |
78 { | 143 { |
79 if (started_) | 144 AddCommand(new InstanceCommand(*this, instance)); |
80 { | 145 } |
81 throw OrthancException(ErrorCode_BadSequenceOfCalls); | 146 |
82 } | 147 |
83 else | 148 void SetOfInstancesJob::AddTrailingStep() |
84 { | 149 { |
85 instances_.push_back(instance); | 150 AddCommand(new TrailingStepCommand(*this)); |
86 } | 151 hasTrailingStep_ = true; |
87 } | 152 } |
88 | 153 |
89 | 154 |
90 void SetOfInstancesJob::SetPermissive(bool permissive) | 155 size_t SetOfInstancesJob::GetInstancesCount() const |
91 { | 156 { |
92 if (started_) | 157 if (hasTrailingStep_) |
93 { | 158 { |
94 throw OrthancException(ErrorCode_BadSequenceOfCalls); | 159 assert(GetCommandsCount() > 0); |
95 } | 160 return GetCommandsCount() - 1; |
96 else | 161 } |
97 { | 162 else |
98 permissive_ = permissive; | 163 { |
99 } | 164 return GetCommandsCount(); |
165 } | |
166 } | |
167 | |
168 | |
169 const std::string& SetOfInstancesJob::GetInstance(size_t index) const | |
170 { | |
171 if (index >= GetInstancesCount()) | |
172 { | |
173 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
174 } | |
175 else | |
176 { | |
177 return dynamic_cast<const InstanceCommand&>(GetCommand(index)).GetInstance(); | |
178 } | |
179 } | |
180 | |
181 | |
182 void SetOfInstancesJob::Start() | |
183 { | |
184 SetOfCommandsJob::Start(); | |
100 } | 185 } |
101 | 186 |
102 | 187 |
103 void SetOfInstancesJob::Reset() | 188 void SetOfInstancesJob::Reset() |
104 { | 189 { |
105 if (started_) | 190 SetOfCommandsJob::Reset(); |
106 { | 191 |
107 position_ = 0; | 192 failedInstances_.clear(); |
108 failedInstances_.clear(); | 193 } |
109 } | 194 |
110 else | 195 |
111 { | 196 void SetOfInstancesJob::GetPublicContent(Json::Value& target) |
112 throw OrthancException(ErrorCode_BadSequenceOfCalls); | 197 { |
113 } | 198 SetOfCommandsJob::GetPublicContent(target); |
114 } | 199 target["InstancesCount"] = static_cast<uint32_t>(GetInstancesCount()); |
115 | 200 target["FailedInstancesCount"] = static_cast<uint32_t>(failedInstances_.size()); |
116 | 201 } |
117 float SetOfInstancesJob::GetProgress() | 202 |
118 { | 203 |
119 const size_t steps = GetStepsCount(); | 204 |
120 | 205 static const char* KEY_TRAILING_STEP = "TrailingStep"; |
121 if (steps == 0) | |
122 { | |
123 return 0; | |
124 } | |
125 else | |
126 { | |
127 return (static_cast<float>(position_) / | |
128 static_cast<float>(steps)); | |
129 } | |
130 } | |
131 | |
132 | |
133 const std::string& SetOfInstancesJob::GetInstance(size_t index) const | |
134 { | |
135 if (index >= instances_.size()) | |
136 { | |
137 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
138 } | |
139 else | |
140 { | |
141 return instances_[index]; | |
142 } | |
143 } | |
144 | |
145 | |
146 JobStepResult SetOfInstancesJob::Step() | |
147 { | |
148 if (!started_) | |
149 { | |
150 throw OrthancException(ErrorCode_InternalError); | |
151 } | |
152 | |
153 const size_t steps = GetStepsCount(); | |
154 | |
155 if (steps == 0 && | |
156 position_ == 0) | |
157 { | |
158 // Nothing to handle (no instance, nor trailing step): We're done | |
159 position_ = 1; | |
160 return JobStepResult::Success(); | |
161 } | |
162 | |
163 if (position_ >= steps) | |
164 { | |
165 // Already done | |
166 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
167 } | |
168 | |
169 bool isTrailingStep = (hasTrailingStep_ && | |
170 position_ + 1 == steps); | |
171 | |
172 bool ok; | |
173 | |
174 try | |
175 { | |
176 if (isTrailingStep) | |
177 { | |
178 ok = HandleTrailingStep(); | |
179 } | |
180 else | |
181 { | |
182 // Not at the trailing step: Handle the current instance | |
183 ok = HandleInstance(instances_[position_]); | |
184 } | |
185 | |
186 if (!ok && !permissive_) | |
187 { | |
188 return JobStepResult::Failure(ErrorCode_InternalError); | |
189 } | |
190 } | |
191 catch (OrthancException&) | |
192 { | |
193 if (permissive_) | |
194 { | |
195 ok = false; | |
196 } | |
197 else | |
198 { | |
199 throw; | |
200 } | |
201 } | |
202 | |
203 if (!ok && | |
204 !isTrailingStep) | |
205 { | |
206 failedInstances_.insert(instances_[position_]); | |
207 } | |
208 | |
209 position_ += 1; | |
210 | |
211 if (position_ == steps) | |
212 { | |
213 // We're done | |
214 return JobStepResult::Success(); | |
215 } | |
216 else | |
217 { | |
218 return JobStepResult::Continue(); | |
219 } | |
220 } | |
221 | |
222 | |
223 | |
224 static const char* KEY_DESCRIPTION = "Description"; | |
225 static const char* KEY_PERMISSIVE = "Permissive"; | |
226 static const char* KEY_POSITION = "Position"; | |
227 static const char* KEY_TYPE = "Type"; | |
228 static const char* KEY_INSTANCES = "Instances"; | |
229 static const char* KEY_FAILED_INSTANCES = "FailedInstances"; | 206 static const char* KEY_FAILED_INSTANCES = "FailedInstances"; |
230 static const char* KEY_TRAILING_STEP = "TrailingStep"; | 207 |
231 | 208 bool SetOfInstancesJob::Serialize(Json::Value& target) |
232 | 209 { |
233 void SetOfInstancesJob::GetPublicContent(Json::Value& value) | 210 if (SetOfCommandsJob::Serialize(target)) |
234 { | 211 { |
235 value[KEY_DESCRIPTION] = GetDescription(); | 212 target[KEY_TRAILING_STEP] = hasTrailingStep_; |
236 value["InstancesCount"] = static_cast<uint32_t>(instances_.size()); | 213 SerializationToolbox::WriteSetOfStrings(target, failedInstances_, KEY_FAILED_INSTANCES); |
237 value["FailedInstancesCount"] = static_cast<uint32_t>(failedInstances_.size()); | 214 return true; |
238 } | 215 } |
239 | 216 else |
240 | 217 { |
241 bool SetOfInstancesJob::Serialize(Json::Value& value) | 218 return false; |
242 { | 219 } |
243 value = Json::objectValue; | 220 } |
244 | 221 |
245 std::string type; | 222 |
246 GetJobType(type); | 223 SetOfInstancesJob::SetOfInstancesJob(const Json::Value& source) : |
247 value[KEY_TYPE] = type; | 224 SetOfCommandsJob(new InstanceUnserializer(*this), source) |
248 | 225 { |
249 value[KEY_PERMISSIVE] = permissive_; | 226 SerializationToolbox::ReadSetOfStrings(failedInstances_, source, KEY_FAILED_INSTANCES); |
250 value[KEY_POSITION] = static_cast<unsigned int>(position_); | 227 |
251 value[KEY_DESCRIPTION] = description_; | 228 if (source.isMember(KEY_TRAILING_STEP)) |
252 value[KEY_TRAILING_STEP] = hasTrailingStep_; | 229 { |
253 | 230 hasTrailingStep_ = SerializationToolbox::ReadBoolean(source, KEY_TRAILING_STEP); |
254 SerializationToolbox::WriteArrayOfStrings(value, instances_, KEY_INSTANCES); | |
255 SerializationToolbox::WriteSetOfStrings(value, failedInstances_, KEY_FAILED_INSTANCES); | |
256 | |
257 return true; | |
258 } | |
259 | |
260 | |
261 SetOfInstancesJob::SetOfInstancesJob(const Json::Value& value) : | |
262 started_(false), | |
263 permissive_(SerializationToolbox::ReadBoolean(value, KEY_PERMISSIVE)), | |
264 position_(SerializationToolbox::ReadUnsignedInteger(value, KEY_POSITION)), | |
265 description_(SerializationToolbox::ReadString(value, KEY_DESCRIPTION)) | |
266 { | |
267 SerializationToolbox::ReadArrayOfStrings(instances_, value, KEY_INSTANCES); | |
268 SerializationToolbox::ReadSetOfStrings(failedInstances_, value, KEY_FAILED_INSTANCES); | |
269 | |
270 if (value.isMember(KEY_TRAILING_STEP)) | |
271 { | |
272 hasTrailingStep_ = SerializationToolbox::ReadBoolean(value, KEY_TRAILING_STEP); | |
273 } | 231 } |
274 else | 232 else |
275 { | 233 { |
276 // Backward compatibility with Orthanc <= 1.4.2 | 234 // Backward compatibility with Orthanc <= 1.4.2 |
277 hasTrailingStep_ = false; | 235 hasTrailingStep_ = false; |
278 } | 236 } |
279 | 237 } |
280 if (position_ > GetStepsCount() + 1) | 238 |
281 { | 239 |
282 throw OrthancException(ErrorCode_BadFileFormat); | |
283 } | |
284 } | |
285 } | 240 } |