Command.h
1 /*
2 
3 MIT License
4 
5 Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6 
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
13 
14 The above copyright notice and this permission notice shall be included in all
15 copies or substantial portions of the Software.
16 
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 SOFTWARE.
24 
25 */
26 /*
27 Part of Rack development has been done in the BALTRAD projects part-financed
28 by the European Union (European Regional Development Fund and European
29 Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30 */
31 
32 #ifndef DRAINLET_H_
33 #define DRAINLET_H_
34 
35 //#include <map>
36 //#include <set>
37 //#include "drain/util/Debug.h"
38 //#include "drain/util/ReferenceMap.h"
39 
40 #include <drain/Log.h>
41 #include "drain/util/BeanLike.h"
42 #include "drain/util/ReferenceMap.h"
43 #include "drain/util/VariableMap.h"
44 
45 //#include "drain/util/Cloner.h"
46 #include "Context.h"
47 
48 namespace drain {
49 
51 
54 class Command : public Contextual {
55 
56 public:
57 
58  inline
59  Command(): section(0){}; //
60 
61  inline
62  Command(const Command & cmd) : section(cmd.section), lastParameters(cmd.lastParameters){
63  // setParameters(cmd.getParameters()); they do not exist yet!
64  }
65 
66  virtual inline
67  ~Command(){};
68 
69  // TODO: getFullName(), the "C++ name" of this (derived) class.
70  // Typically not same as the command line command.
71 
72  virtual
73  const std::string & getName() const = 0;
74 
75  virtual
76  const std::string & getDescription() const = 0;
77 
78  virtual
79  const ReferenceMap & getParameters() const = 0;
80 
81  static
82  const SprinterLayout cmdArgLayout; // = {",", "?", "=", ""};
83 
84 protected:
85 
86  virtual
87  ReferenceMap & getParameters() = 0;
88 
89 public:
90 
91  virtual
92  void setParameters(const std::string & args) final;
93  /*
94  {
95  lastParameters = args;
96  setAllParameters(args);
97  };
98  */
99 
100 
101  // TODO: remove
102  // virtual
103  // void setParameters(const VariableMap & args) final; // REDESIGN?
104 
105  // virtual
106  // void setParameters(const VariableMap & args) = 0; // REDESIGN?
107 
108 
109  // TODO: make this a loop calling set(key,val)
110  template <class T>
111  void setParameters(const SmartMap<T> & args){
112  // TODO: set parameter X=Y ?
113  /*
114  VariableMap vargs;
115  vargs.importCastableMap(args);
116  setParameters(vargs);
117  */
118  ReferenceMap & parameters = getParameters();
119  std::stringstream sstr;
120  char separator = 0;
121  for (const auto & entry: args){
122  parameters[entry.first] = entry.second;
123  // setParameter(entry.first, entry.second);
124  if (separator)
125  sstr << separator;
126  else
127  separator = ',';
128  sstr << entry.first << '=' << entry.second;
129  }
130  lastParameters = sstr.str();
131 
132  }
133 
135 
139  template <class T>
140  void setParameter(const std::string & key, const T & value){
141  getParameters()[key] = value;
142  std::stringstream sstr;
143  sstr << key << '=' << value;
144  lastParameters = sstr.str();
145  }
146 
147 
148  inline
149  Command & addSection(drain::Flagger::ivalue_t i){
150  section |= i;
151  return *this;
152  }
153 
155 
158  virtual
159  void update(){
160  }
161 
162 
163 
164  //virtual
165  //void setParameters(const SmartMapBase & params) = 0;
166 
167  // Could also need/replace void setParameters(const std::map<std::string,T> & p)
168 
169  // Rename: hasParameters
170  inline
171  bool hasParameters() const { // tODO rename
172 
173  Logger mout(__FILE__, __FUNCTION__);
174 
175  const ReferenceMap & params = this->getParameters();
176  //mout.warn(params );
177 
178  const ReferenceMap::const_iterator it = params.begin();
179  if (it == params.end()) // empty
180  return false;
181  else
182  return it->second.getType() != typeid(void); // ???
183  };
184 
186  virtual inline
187  const std::string & getType() const {
188  static const std::string empty;
189  return empty;
190  };
191 
193  virtual inline
194  void exec() const {};
195 
197 
200  virtual
201  inline
202  void run(const std::string & params = ""){
203  setParameters(params);
204  update();
205  exec();
206  }
207 
208 
209  // Optional bit(s) marking the command type (compare with manual page sections)
213  int section = 1;
214 
216  // bool execRoutine; -> see section flag TriggerSection;
217 
219  // virtual void setKey(const std::string & key) const {}
220 
221  inline
222  const std::string & getLastParameters() const {
223  return lastParameters;
224  };
225 
226 protected:
227 
228  // virtual
229  // void setAllParameters(const std::string & args); // = 0;
230 
231  std::string lastParameters;
232 
233 
234 };
235 
236 inline
237 std::ostream & operator<<(std::ostream & ostr, const Command &cmd){
238  ostr << cmd.getName();
239  if (cmd.hasParameters()){
240  ostr << ' ' << cmd.getParameters(); // << ' ';
241  }
242  return ostr;
243 }
244 
245 // See new implementations in CommandBank, CommandUtils.
246 //typedef std::list<std::pair<Command &, std::string> > Script; // TODO: move
247 
248 
250 /*
251 template <class B>
252 class BeanerCommand : public Command {
253 
254 public:
255 
256  typedef B bean_t;
257 
258  // Main
259  virtual
260  const bean_t & getBean() const = 0;
261 
262  // Main
263  virtual
264  bean_t & getBean() = 0;
265 
266 
267 
268 
269  inline
270  const std::string & getName() const final {
271  return getBean().getName();
272  };
273 
274  inline
275  const std::string & getDescription() const final {
276  return getBean().getDescription();
277  };
278 
279  virtual inline
280  const drain::ReferenceMap & getParameters() const final {
281  return getBean().getParameters();
282  };
283 
284 protected:
285 
286  virtual inline
287  drain::ReferenceMap & getParameters() final {
288  return getBean().getParameters();
289  };
290 
291 };
292 */
293 
295 
301 template <class B, class B2=B>
302 class BeanCommand : public Command {
303 // class BeanCommand : public BeanerCommand<B> { // public Command {
304 
305 public:
306 
307  BeanCommand(){
308  };
309 
310  BeanCommand(const std::string & name, const std::string & description) : bean(name, description){
311  };
312 
313 
314  BeanCommand(const BeanCommand & cmd) : Command(cmd), bean(cmd.bean) {
315  // WARNING: this may have undesired beaviour:
316  // If B2 is (Bean &), also new instance of beanCmd.bean -> cmd.bean
317  };
318 
319  BeanCommand(B & b) : bean(b) {
320  };
321 
322  typedef B bean_t;
323 
324 // Consider private:
325  B2 bean;
326 
327 
328  virtual inline
329  const bean_t & getBean() const { // final
330  return bean;
331  };
332 
333  // Main
334  virtual inline
335  bean_t & getBean() { // final
336  return bean;
337  };
338 
339 
340 
341  inline
342  const std::string & getName() const final {
343  return getBean().getName();
344  };
345 
346  inline
347  const std::string & getDescription() const final {
348  return getBean().getDescription();
349  };
350 
351  virtual inline
352  const drain::ReferenceMap & getParameters() const final {
353  return getBean().getParameters();
354  };
355 
356 protected:
357 
358  virtual inline
359  drain::ReferenceMap & getParameters() final {
360  return getBean().getParameters();
361  };
362 
363 
364  /*
365  virtual
366  void setAllParameters(const std::string & args) override {
367 
368  Context & ctx = this->template getContext<>();
369  drain::Logger mout(ctx.log, __FUNCTION__, this->bean.getName() );
370 
371  bean.setParameters(args,'=');
372  //mout.note() = "updating";
373  //this->update();
374  }
375  */
376 
378  //virtual
379  /*
380  void setParameters(const VariableMap & params){
381  bean.setParameters(params);
382  // this->update();
383  }
384  */
385 
386 };
387 
388 
389 
390 template <class B>
391 class BeanRefCommand : public drain::BeanCommand<B, B&> {
392 
393 public:
394 
395  BeanRefCommand(B & bean) : drain::BeanCommand<B,B&>(bean){
396  }
397 
398  BeanRefCommand(const B & bean) : drain::BeanCommand<B,B&>(bean){
399  }
400 
401  BeanRefCommand(const BeanRefCommand<B> & beanRefCmd) : drain::BeanCommand<B,B&>(beanRefCmd.bean){
402  }
403 
404 
405 };
406 
407 
408 
409 
411 
416 //class BasicCommand : public Command { // Todo consider BeanLike
417 class BasicCommand : public BeanCommand<BeanLike> { // Todo consider BeanLike
418 
419 public:
420 
421  BasicCommand(const std::string & name, const std::string & description);
422 
423  inline
424  //BasicCommand(const BasicCommand & cmd): Command(cmd), name(cmd.name), description(cmd.description) {
425  BasicCommand(const BasicCommand & cmd): BeanCommand<BeanLike>(cmd) {
426  // remember to call importParameters()
427  }
428 
429 /* 2024
430  virtual inline
431  const std::string & getName() const { return name; };
432 
433  virtual inline
434  const std::string & getDescription() const { return description; };
435 
436  virtual inline
437  const ReferenceMap & getParameters() const { return parameters; };
438 
439 protected:
440 
441  virtual inline
442  ReferenceMap & getParameters(){
443  return parameters;
444  };
445 
446 public:
447 
448 */
449  /*
450  virtual
451  void setAllParameters(const std::string & args) override; //, char assignmentSymbol='=');
452  */
453 
454  /*
455  inline
456  void setParameters(const VariableMap & params){
457  parameters.importCastableMap(params);
458  lastParameters = sprinter(parameters, Sprinter::cmdLineLayout);
459  //this->update();
460  }
461  */
462 
463  /* 2024
464  template <class T>
465  inline
466  void setParameters(const SmartMap<T> & params){
467  parameters.importCastableMap(params);
468  }
469  */
470 
471  /*
472  template <class T>
473  void setParameter(const std::string & key, const T & value) {
474  parameters[key] = value;
475  //this->update();
476  }
477  */
478 
479 
480 /* 2024
481 protected:
482 
483  const std::string name;
484 
485  const std::string description;
486 
487  ReferenceMap parameters;
488 
489  */
490 
491 };
492 
493 
494 
495 
497 
500 template <class T = std::string>
501 class SimpleCommand : public BasicCommand {
502 
503 public:
504 
505  T value;
506 
507  SimpleCommand(const std::string & name, const std::string & description,
508  const std::string & key="value", const T & initValue = T(), const std::string & unit = "") : BasicCommand(name, description) {
509 
510  getParameters().separator = '\0';
511  getParameters().link(key, value = initValue, unit);
512 
513  if (key.empty()){
514  Context & ctx = getContext<Context>();
515  drain::Logger mout(ctx.log,__FILE__, __FUNCTION__);
516  mout.warn("Empty value key in command ", name, " (", description, ")");
517  }
518 
519 
520  };
521 
523  template <class S>
524  SimpleCommand(const std::string & name, const std::string & description,
525  const std::string & key, std::initializer_list<S> l , const std::string & unit = "") : BasicCommand(name, description) {
526  // parameters.separator = '\0';
527  value = l;
528  getParameters().link(key, value);
529 
530  if (key.empty()){
531  Context & ctx = getContext<Context>();
532  drain::Logger mout(ctx.log,__FILE__, __FUNCTION__);
533  mout.warn("Empty value key in command ", name, " (", description, ")");
534  }
535  };
536 
537 
538  SimpleCommand(const SimpleCommand & cmd): BasicCommand(cmd) {
539  getParameters().separator = '\0';
540  getParameters().copyStruct(cmd.getParameters(), cmd, *this);
541  /*
542  parameters.separator = '\0';
543  parameters.copyStruct(cmd.getParameters(), cmd, *this);
544  */
545  };
546 
547  /*
548  void setParameters(const std::string & args){
549  const std::string & key = parameters.begin()->first;
550  Variable v(typeid(T));
551  if (key.empty()){
552  v = args;
553  }
554  else {
555  const std::string assignment = key+"=";
556  const size_t n = assignment.length();
557  if (args.compare(0,n,key)==0){
558  v = args.substr(n);
559  }
560  else
561  v = args;
562  }
563  value = v;
564  }
565  */
566 
567 
568 
569 };
570 
572 
575 /*
576 class DynamicCommand : public drain::Command {
577 
578 public:
579 
580  virtual
581  void exec() const {
582  Context & ctx = getContext<Context>();
583  drain::Logger mout(ctx.log,__FILE__, __FUNCTION__);
584  mout.note("I am " , getName() , ", invoked as " , key );
585  }
586 
587  virtual
588  void setKey(const std::string & cmdKey) const {
589  key = cmdKey;
590  }
591 
592 protected:
593 
594  mutable
595  std::string key;
596 
597 };
598 */
599 
600 
601 
602 
603 } // drain::
604 
605 #endif /* DRAINLET_H_ */
Simple implementation of Command: adds name , description and parameters .
Definition: Command.h:417
Retrieves bean dynamically for each call.
Definition: Command.h:302
Definition: Command.h:391
Base class for commands: typically actions taking parameters but also plain variable assignments and ...
Definition: Command.h:54
virtual void exec() const
Run the command with current parameter values.
Definition: Command.h:194
void setParameter(const std::string &key, const T &value)
Set a value to a single parameter.
Definition: Command.h:140
int section
Definition: Command.h:213
virtual const std::string & getType() const
Description of result, comparable to a return type of a function. ?
Definition: Command.h:187
virtual void update()
Optional method for preparing command to execution.
Definition: Command.h:159
const std::string & getLastParameters() const
After executing this command run a routine, if defined.
Definition: Command.h:222
virtual void run(const std::string &params="")
Convenience. Sets parameters and executes the command.
Definition: Command.h:202
Definition: Context.h:57
Definition: Context.h:245
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition: Log.h:308
Logger & warn(const TT &... args)
Possible error, but execution can continue.
Definition: Log.h:426
Definition: ReferenceMap.h:207
void copyStruct(const ReferenceMap &m, const T &src, T &dst, extLinkPolicy policy=RESERVE)
Experimental. Copies references and values of a structure to another.
Definition: ReferenceMap.h:399
A single-parameter command.
Definition: Command.h:501
SimpleCommand(const std::string &name, const std::string &description, const std::string &key, std::initializer_list< S > l, const std::string &unit="")
Constuctor designer for SimpleCommand<Unituple<> > .
Definition: Command.h:524
A base class for smart maps providing methods for importing and exporting values, among others.
Definition: SmartMap.h:66
char separator
Default character used for splitting input and output. See setValues.
Definition: SmartMap.h:85
Definition: DataSelector.cpp:1277
Definition: Sprinter.h:137