Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
berryParameterizedCommand.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 BlueBerry Platform
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
18 
19 #include "berryIParameter.h"
20 #include "berryIParameterValues.h"
21 #include "berryCommand.h"
22 #include "berryParameterization.h"
23 #include "berryExecutionEvent.h"
24 #include "berryCommandManager.h"
25 #include "berryCommandCategory.h"
26 #include "berryState.h"
27 #include "berryIHandler.h"
28 
29 #include "internal/berryCommandUtils.h"
30 
31 #include <berryObjectString.h>
32 
33 
34 namespace berry
35 {
36 
37 const uint ParameterizedCommand::HASH_CODE_NOT_COMPUTED = 0;
38 const uint ParameterizedCommand::HASH_FACTOR = 89;
39 const uint ParameterizedCommand::HASH_INITIAL = qHash("berry::ParameterizedCommand");
40 
42  const QList<Parameterization>& params)
43  : command(command), hashCode(HASH_CODE_NOT_COMPUTED)
44 {
45  if (!command)
46  {
47  throw Poco::NullPointerException(
48  "A parameterized command cannot have a null command");
49  }
50 
51  QList<IParameter::Pointer> parameters;
52  try
53  {
54  parameters = command->GetParameters();
55  } catch (const NotDefinedException* /*e*/)
56  {
57  // This should not happen.
58  }
59  if (!params.empty() && !parameters.empty())
60  {
61  for (int j = 0; j < parameters.size(); j++)
62  {
63  for (int i = 0; i < params.size(); i++)
64  {
65  if (parameters[j] == params[i].GetParameter())
66  {
67  this->parameterizations.push_back(params[i]);
68  }
69  }
70  }
71  }
72 }
73 
74 bool ParameterizedCommand::operator<(const Object* object) const
75 {
76  const ParameterizedCommand* command = dynamic_cast<const ParameterizedCommand*>(object);
77  const bool thisDefined = this->command->IsDefined();
78  const bool otherDefined = command->command->IsDefined();
79  if (!thisDefined || !otherDefined)
80  {
81  return CommandUtils::Compare(thisDefined, otherDefined) < 0;
82  }
83 
84  try
85  {
86  const int compareTo = this->GetName().compare(command->GetName());
87  if (compareTo == 0)
88  {
89  return (this->GetId() < command->GetId());
90  }
91  return compareTo < 0;
92  }
93  catch (const NotDefinedException* /*e*/)
94  {
95  throw CommandException(
96  "Concurrent modification of a command's defined state");
97  }
98 }
99 
100 bool ParameterizedCommand::operator==(const Object* object) const
101 {
102  if (this == object)
103  {
104  return true;
105  }
106 
107  if (const ParameterizedCommand* command = dynamic_cast<const ParameterizedCommand*>(object))
108  {
109  if (!(this->command == command->command))
110  {
111  return false;
112  }
113 
114  return CommandUtils::Equals(this->parameterizations, command->parameterizations);
115  }
116 
117  return false;
118 }
119 
121  const Object::Pointer& applicationContext)
122 {
123  ExecutionEvent::Pointer excEvent(new ExecutionEvent(command,
124  this->GetParameterMap(), trigger, applicationContext));
125  return command->ExecuteWithChecks(excEvent);
126 }
127 
129 {
130  return command;
131 }
132 
134 {
135  return command->GetId();
136 }
137 
139 {
140  if (name.isEmpty())
141  {
142  QTextStream nameBuffer(&name);
143  nameBuffer << command->GetName() << " (";
144  const unsigned int parameterizationCount = (unsigned int) parameterizations.size();
145  for (unsigned int i = 0; i < parameterizationCount; i++)
146  {
147  const Parameterization& parameterization = parameterizations[i];
148  nameBuffer << parameterization.GetParameter()->GetName() << ": ";
149  try
150  {
151  nameBuffer << parameterization.GetValueName();
152  }
153  catch (const ParameterValuesException& /*e*/)
154  {
155  /*
156  * Just let it go for now. If someone complains we can
157  * add more info later.
158  */
159  }
160 
161  // If there is another item, append a separator.
162  if (i + 1 < parameterizationCount)
163  {
164  nameBuffer << ", ";
165  }
166 
167  nameBuffer << ")";
168  }
169  }
170  return name;
171 }
172 
173 QHash<QString, QString> ParameterizedCommand::GetParameterMap() const
174 {
175  QHash<QString, QString> parameterMap;
176  for (int i = 0; i < parameterizations.size(); i++)
177  {
178  const Parameterization& parameterization = parameterizations[i];
179  parameterMap.insert(parameterization.GetParameter()->GetId(),
180  parameterization.GetValue());
181  }
182  return parameterMap;
183 }
184 
186 {
187  if (hashCode == HASH_CODE_NOT_COMPUTED)
188  {
189  hashCode = HASH_INITIAL * HASH_FACTOR + (command ? command->HashCode() : 0);
190  hashCode = hashCode * HASH_FACTOR;
191  for (int i = 0; i < parameterizations.size(); i++)
192  {
193  hashCode += parameterizations[i].HashCode();
194  }
195 
196  if (hashCode == HASH_CODE_NOT_COMPUTED)
197  {
198  hashCode++;
199  }
200  }
201  return hashCode;
202 }
203 
205 {
206  const QString escapedId(this->Escape(this->GetId()));
207 
208  if (parameterizations.empty())
209  {
210  return escapedId;
211  }
212 
213  QString str;
214  QTextStream buffer(&str);
216 
217  for (int i = 0; i < parameterizations.size(); i++)
218  {
219 
220  if (i> 0)
221  {
222  // insert separator between parameters
224  }
225 
226  const Parameterization& parameterization = parameterizations[i];
227  const QString parameterId(parameterization.GetParameter()->GetId());
228  const QString escapedParameterId(this->Escape(parameterId));
229 
230  buffer << escapedParameterId;
231 
232  const QString parameterValue(parameterization.GetValue());
233  if (!parameterValue.isEmpty())
234  {
235  const QString escapedParameterValue(this->Escape(parameterValue));
237  << escapedParameterValue;
238  }
239  }
240 
242 
243  return str;
244 }
245 
247 {
248  QString str;
249  QTextStream buffer(&str);
250  buffer << "ParameterizedCommand(" << command->ToString() << ","
251  << CommandUtils::ToString(parameterizations) << ")";
252  return str;
253 }
254 
255 QList<ParameterizedCommand::Pointer>
257 {
258  QList<IParameter::Pointer> parameters(command->GetParameters());
259 
260  typedef QList<QList<Parameterization> > ExpandedParamsType;
261  const ExpandedParamsType expansion(ExpandParameters(0, parameters));
262  QList<ParameterizedCommand::Pointer> combinations;
263 
264  for (ExpandedParamsType::const_iterator expansionItr = expansion.begin();
265  expansionItr != expansion.end(); ++expansionItr)
266  {
267  QList<Parameterization> combination(*expansionItr);
268 
269  QList<Parameterization> parameterizations(combination);
271  parameterizations));
272  combinations.push_back(pCmd);
273  }
274 
275  return combinations;
276 }
277 
279  const QHash<QString, Object::Pointer>& parameters)
280 {
281  // no parameters
282  if (parameters.empty())
283  {
284  ParameterizedCommand::Pointer pCmd(new ParameterizedCommand(command, QList<Parameterization>()));
285  return pCmd;
286  }
287 
288  try
289  {
290  QList<Parameterization> parms;
291 
292  // iterate over given parameters
293  for (QHash<QString, Object::Pointer>::const_iterator i = parameters.begin();
294  i != parameters.end(); ++i)
295  {
296  QString key(i.key());
297 
298  // get the parameter from the command
299  IParameter::Pointer parameter(command->GetParameter(key));
300 
301  // if the parameter is defined add it to the parameter list
302  if (!parameter)
303  {
304  return ParameterizedCommand::Pointer(nullptr);
305  }
306  ParameterType::Pointer parameterType(command->GetParameterType(key));
307  if (!parameterType)
308  {
309  QString val = i.value()->ToString();
310  parms.push_back(Parameterization(parameter, val));
311  }
312  else
313  {
314  IParameterValueConverter* valueConverter(parameterType->GetValueConverter());
315  if (valueConverter)
316  {
317  QString val(valueConverter->ConvertToString(i.value()));
318  parms.push_back(Parameterization(parameter, val));
319  }
320  else
321  {
322  QString val = i.value()->ToString();
323  parms.push_back(Parameterization(parameter, val));
324  }
325  }
326  }
327 
328  // convert the parameters to an Parameterization array and create
329  // the command
330  ParameterizedCommand::Pointer pCmd(new ParameterizedCommand(command, parms));
331  return pCmd;
332  }
333  catch (const NotDefinedException* /*e*/)
334  {
335  }
336  catch (const ParameterValueConversionException* /*e*/)
337  {
338  }
339  return ParameterizedCommand::Pointer(nullptr);
340 }
341 
342 QString ParameterizedCommand::Escape(const QString& rawText)
343 {
344 
345  QString buffer;
346 
347  for (QString::const_iterator i = rawText.begin();
348  i != rawText.end(); ++i)
349  {
350 
351  QString::value_type c = *i;
357  {
358  buffer += CommandManager::ESCAPE_CHAR;
359  }
360 
361  buffer += c;
362  }
363 
364  if (buffer.isEmpty())
365  {
366  return rawText;
367  }
368  return buffer;
369 }
370 
371 QList<QList<Parameterization> > ParameterizedCommand::ExpandParameters(
372  unsigned int startIndex, const QList<IParameter::Pointer>& parameters)
373 {
374  typedef QList<QList<Parameterization> > ReturnType;
375 
376  const int nextIndex = startIndex + 1;
377  const bool noMoreParameters = (nextIndex >= parameters.size());
378 
379  const IParameter::Pointer parameter(parameters[startIndex]);
380  ReturnType parameterizations;
381 
382  if (parameter->IsOptional())
383  {
384  parameterizations.push_back(QList<Parameterization>());
385  }
386 
387  IParameterValues* values = nullptr;
388  try
389  {
390  values = parameter->GetValues();
391  }
392  catch (const ParameterValuesException& /*e*/)
393  {
394  if (noMoreParameters)
395  {
396  return parameterizations;
397  }
398 
399  // Make recursive call
400  return ExpandParameters(nextIndex, parameters);
401  }
402 
403  const QHash<QString,QString> parameterValues = values->GetParameterValues();
404  for (IParameter::ParameterValues::const_iterator parameterValueItr =
405  parameterValues.begin(); parameterValueItr != parameterValues.end(); ++parameterValueItr)
406  {
407  QList<Parameterization> combination;
408  combination.push_back(
409  Parameterization(parameter, parameterValueItr.value()));
410  parameterizations.push_back(combination);
411  }
412 
413  // Check if another iteration will produce any more names.
414  if (noMoreParameters)
415  {
416  // This is it, so just return the current parameterizations.
417  return parameterizations;
418  }
419 
420  // Make recursive call
421  ReturnType suffixes(ExpandParameters(nextIndex, parameters));
422  if (suffixes.empty())
423  {
424  // This is it, so just return the current parameterizations.
425  return parameterizations;
426  }
427 
428  ReturnType returnValue;
429  for (ReturnType::iterator suffixItr = suffixes.begin(); suffixItr
430  != suffixes.end(); ++suffixItr)
431  {
432  for (ReturnType::iterator combinationItr = parameterizations.begin(); combinationItr
433  != parameterizations.end(); ++combinationItr)
434  {
435  QList<Parameterization> newCombination(*combinationItr);
436  newCombination.append(*suffixItr);
437  returnValue.push_back(newCombination);
438  }
439  }
440 
441  return returnValue;
442 }
443 
444 }
static const char PARAMETER_START_CHAR
Light weight base class for most BlueBerry classes.
Definition: berryObject.h:78
SmartPointer< const IParameter > GetParameter() const
static const char ESCAPE_CHAR
Implements transparent reference counting.
static ParameterizedCommand::Pointer GenerateCommand(const SmartPointer< Command > command, const QHash< QString, Object::Pointer > &parameters)
Object::Pointer ExecuteWithChecks(const Object::ConstPointer &trigger, const Object::Pointer &applicationContext)
berry::SmartPointer< Self > Pointer
Definition: berryObject.h:88
static const char PARAMETER_END_CHAR
QHash< QString, QString > GetParameterMap() const
ParameterizedCommand(const SmartPointer< Command > &command, const QList< Parameterization > &parameterizations)
static const char PARAMETER_SEPARATOR_CHAR
unsigned int uint
static const char ID_VALUE_CHAR
bool operator==(const Object *object) const override
SmartPointer< Command > GetCommand() const
static QList< ParameterizedCommand::Pointer > GenerateCombinations(const SmartPointer< Command > command)
bool operator<(const Object *object) const override
uint qHash(const berry::Object &o)