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 }