lsst.pex.policy  16.0-2-gf41ba6b+4
Policy.cc
Go to the documentation of this file.
1 /*
2  * LSST Data Management System
3  * Copyright 2008, 2009, 2010 LSST Corporation.
4  *
5  * This product includes software developed by the
6  * LSST Project (http://www.lsst.org/).
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the LSST License Statement and
19  * the GNU General Public License along with this program. If not,
20  * see <http://www.lsstcorp.org/LegalNotices/>.
21  */
22 
26 #include "lsst/pex/policy/Policy.h"
32 // #include "lsst/pex/logging/Trace.h"
33 
34 #include <memory>
35 #include <boost/filesystem/path.hpp>
36 
37 #include <stdexcept>
38 #include <string>
39 #include <cctype>
40 #include <algorithm>
41 #include <sstream>
42 
43 using namespace std;
44 namespace fs = boost::filesystem;
46 namespace dafBase = lsst::daf::base;
47 
48 namespace lsst {
49 namespace pex {
50 namespace policy {
51 
52 //@cond
53 
56 
57 const char * const Policy::typeName[] = {
58  "undefined",
59  "bool",
60  "int",
61  "double",
62  "string",
63  "Policy",
64  "PolicyFile"
65 };
66 
67 /*
68  * Create an empty policy
69  */
70 Policy::Policy()
71  : Citizen(typeid(this)), Persistable(), _data(new PropertySet())
72 { }
73 
74 /*
75  * Create policy
76  */
77 Policy::Policy(const PolicySource& source)
78  : Citizen(typeid(this)), Persistable(), _data(new PropertySet())
79 {
80  source.load(*this);
81 }
82 
83 /*
84  * Create a Policy from a named file or URN.
85  */
86 Policy::Policy(const string& pathOrUrn)
87  : Citizen(typeid(this)), Persistable(), _data(new PropertySet())
88 {
89  createPolicyFile(pathOrUrn, true)->load(*this);
90 }
91 
92 /*
93  * Create a Policy from a named file or URN.
94  */
95 Policy::Policy(const char *pathOrUrn)
96  : Citizen(typeid(this)), Persistable(), _data(new PropertySet())
97 {
98  createPolicyFile(pathOrUrn, true)->load(*this);
99 }
100 
108 Policy::FilePtr Policy::createPolicyFile(const string& pathOrUrn, bool strict) {
109  if (UrnPolicyFile::looksLikeUrn(pathOrUrn, strict))
110  // return std::make_shared<PolicyFile>(new UrnPolicyFile(pathOrUrn));
111  return Policy::FilePtr(new UrnPolicyFile(pathOrUrn));
112  else
113  // return std::make_shared<PolicyFile>(new PolicyFile(pathOrUrn));
114  return Policy::FilePtr(new PolicyFile(pathOrUrn));
115 }
116 
117 /* Extract defaults from dict into target. Note any errors in ve. */
118 void extractDefaults(Policy& target, const Dictionary& dict, ValidationError& ve) {
119  list<string> names;
120  dict.definedNames(names);
121 
122  for(list<string>::iterator it = names.begin(); it != names.end(); ++it) {
123  const string& name = *it;
124  std::auto_ptr<Definition> def(dict.makeDef(name));
125  def->setDefaultIn(target, &ve);
126  // recurse into sub-dictionaries
127  if (def->getType() == Policy::POLICY && dict.hasSubDictionary(name)) {
128  Policy::Ptr subp = std::make_shared<Policy>();
129  extractDefaults(*subp, *dict.getSubDictionary(name), ve);
130  if (subp->nameCount() > 0)
131  target.add(name, subp);
132  }
133  }
134 }
135 
149 Policy::Policy(bool validate, const Dictionary& dict,
150  const fs::path& repository)
151  : Citizen(typeid(this)), Persistable(), _data(new PropertySet())
152 {
153  DictPtr loadedDict; // the dictionary that has all policy files loaded
154  if (validate) { // keep loadedDict around for future validation
155  setDictionary(dict);
156  loadedDict = _dictionary;
157  }
158  else { // discard loadedDict when we finish constructor
159  loadedDict.reset(new Dictionary(dict));
160  }
161  loadedDict->loadPolicyFiles(repository, true);
162 
163  ValidationError ve(LSST_EXCEPT_HERE);
164  extractDefaults(*this, *loadedDict, ve);
165  if (ve.getParamCount() > 0) throw ve;
166 }
167 
168 /*
169  * copy a Policy. Sub-policy objects will not be shared.
170  */
171 Policy::Policy(const Policy& pol)
172  : Citizen(typeid(this)), Persistable(), _data()
173 {
174  _data = pol._data->deepCopy();
175 }
176 
177 /*
178  * copy a Policy. Sub-policy objects will be shared unless deep is true
179  */
180 Policy::Policy(Policy& pol, bool deep)
181  : Citizen(typeid(this)), Persistable(), _data()
182 {
183  if (deep)
184  _data = pol._data->deepCopy();
185  else
186  _data = pol._data;
187 }
188 
189 Policy* Policy::_createPolicy(PolicySource& source, bool doIncludes,
190  const fs::path& repository, bool validate)
191 {
192  auto_ptr<Policy> pol(new Policy());
193  source.load(*pol);
194 
195  if (pol->isDictionary()) {
196  Dictionary d(*pol);
197  pol.reset(new Policy(validate, d, repository));
198  }
199 
200  if (doIncludes) pol->loadPolicyFiles(repository, true);
201 
202  return pol.release();
203 }
204 
205 Policy* Policy::_createPolicy(const string& input, bool doIncludes,
206  const fs::path& repository, bool validate)
207 {
208  fs::path repos = repository;
209  if (repos.empty()) {
210  fs::path filepath(input);
211  if (filepath.has_parent_path()) repos = filepath.parent_path();
212  }
213  PolicyFile file(input);
214  return _createPolicy(file, doIncludes, repos, validate);
215 }
216 
217 Policy* Policy::createPolicyFromUrn(const std::string& urn, bool validate)
218 {
219  // Note: Don't request doIncludes because UrnPolicyFile will load the whole
220  // thing anyway.
221  UrnPolicyFile upf(urn, true, true);
222  return _createPolicy(upf, true, fs::path(), false);
223 }
224 
225 /*
226  * Create an empty policy
227  */
228 Policy::~Policy() { }
229 
235 bool Policy::canValidate() const {
236  return static_cast<bool>(_dictionary);
237 }
238 
244  return _dictionary;
245 }
246 
252 void Policy::setDictionary(const Dictionary& dict) {
253  _dictionary = std::make_shared<Dictionary>(dict);
254 }
255 
266 void Policy::validate(ValidationError *errs) const {
267  if (!_dictionary) throw LSST_EXCEPT(DictionaryError, "No dictionary set.");
268  else _dictionary->validate(*this, errs);
269 }
270 
276 Policy::ValueType Policy::getTypeByName(const string& name) {
277  static map<string, Policy::ValueType> nameTypeMap;
278 
279  if (nameTypeMap.size() == 0) {
281  int n = sizeof(Policy::typeName) / sizeof(char *);
282  for (int i = 0; i < n; ++i) {
283  // remember both capitalized and lowercase versions (eg Policy)
284  tmp[Policy::typeName[i]] = (Policy::ValueType) i;
285  string lowered(Policy::typeName[i]);
286  transform(lowered.begin(), lowered.end(), lowered.begin(), ::tolower);
287  tmp[lowered] = (Policy::ValueType) i;
288  }
289  // a few extras
290  tmp["file"] = Policy::FILE;
291  tmp["boolean"] = Policy::BOOL;
292  tmp["integer"] = Policy::INT;
293  tmp["undef"] = Policy::UNDEF;
294  // assign after initializationto avoid concurrency problems
295  nameTypeMap = tmp;
296 
297  if (tmp.count(name) == 1) return tmp[name];
298  }
299  else
300  if (nameTypeMap.count(name) == 1) return nameTypeMap[name];
301 
302  throw LSST_EXCEPT(BadNameError, name);
303 }
304 
305 /*
306  * load the names of parameters into a given list.
307  *
308  * @param prepend the names string to prepend to any names found.
309  * @param names the list object to be loaded
310  * @param topLevelOnly if true, only parameter names at the top of the
311  * hierarchy will be returned; no hierarchical
312  * names will be included.
313  * @param append if false, the contents of the given list will
314  * be erased before loading the names.
315  * @param want a bit field indicating which is desired (1=Policies,
316  * 2=PolicyFiles, 4=parameters, 7=all).
317  * @return int the number of names added
318  */
319 int Policy::_names(vector<string>& names,
320  bool topLevelOnly, bool append, int want) const
321 {
322  bool shouldCheck = true;
323  vector<string> src;
324  int have = 0, count = 0;
325  if (want == 1) {
326  src = _data->propertySetNames(topLevelOnly);
327  have = 1;
328  shouldCheck = false;
329  }
330  else if (want == 7)
331  src = _data->names(topLevelOnly);
332  else
333  src = _data->paramNames(topLevelOnly);
334 
335  if (!append) names.erase(names.begin(), names.end());
336 
337  StringArray::iterator i;
338  for(i = src.begin(); i != src.end(); ++i) {
339  if (shouldCheck) {
340  if (isPolicy(*i))
341  have = 1;
342  else if (isFile(*i))
343  have = 2;
344  else
345  have = 4;
346  }
347  if ((have&want) > 0) {
348  names.push_back(*i);
349  count++;
350  }
351  }
352 
353  return count;
354 }
355 
356 /*
357  * load the names of parameters into a given list.
358  *
359  * @param prepend the names string to prepend to any names found.
360  * @param names the list object to be loaded
361  * @param topLevelOnly if true, only parameter names at the top of the
362  * hierarchy will be returned; no hierarchical
363  * names will be included.
364  * @param append if false, the contents of the given list will
365  * be erased before loading the names.
366  * @param want a bit field indicating which is desired (1=Policies,
367  * 2=PolicyFiles, 4=parameters, 7=all).
368  * @return int the number of names added
369  */
370 int Policy::_names(list<string>& names,
371  bool topLevelOnly, bool append, int want) const
372 {
373  bool shouldCheck = true;
374  vector<string> src;
375  int have = 0, count = 0;
376  if (want == 1) {
377  src = _data->propertySetNames(topLevelOnly);
378  have = 1;
379  shouldCheck = false;
380  }
381  else if (want == 7)
382  src = _data->names(topLevelOnly);
383  else
384  src = _data->paramNames(topLevelOnly);
385 
386  if (!append) names.erase(names.begin(), names.end());
387 
388  StringArray::iterator i;
389  for(i = src.begin(); i != src.end(); ++i) {
390  if (shouldCheck) {
391  if (isPolicy(*i))
392  have = 1;
393  else if (isFile(*i))
394  have = 2;
395  else
396  have = 4;
397  }
398  if ((have&want) > 0) {
399  names.push_back(*i);
400  count++;
401  }
402  }
403 
404  return count;
405 }
406 
407 template <class T> void Policy::_validate(const std::string& name, const T& value, int curCount) {
408  if (_dictionary) {
409  try {
410  std::unique_ptr<Definition> def(_dictionary->makeDef(name));
411  def->validateBasic(name, value, curCount);
412  } catch(NameNotFound& e) {
413  ValidationError ve(LSST_EXCEPT_HERE);
414  ve.addError(name, ValidationError::UNKNOWN_NAME);
415  throw ve;
416  }
417  }
418 }
419 
420 template void Policy::_validate<Policy::Ptr>(std::string const&, Policy::Ptr const&, int);
421 template void Policy::_validate<std::string >(std::string const&, std::string const&, int);
422 template void Policy::_validate<bool>(std::string const&, bool const&, int);
423 template void Policy::_validate<double>(std::string const&, double const&, int);
424 template void Policy::_validate<int>(std::string const&, int const&, int);
425 
426 /*
427  * return the type information for the underlying type associated with
428  * a given name.
429  */
430 Policy::ValueType Policy::getValueType(const string& name) const {
431  try {
432  const std::type_info& tp = _data->typeOf(name);
433 
434  // handle the special case of FilePtr first
435  if (tp == typeid(Persistable::Ptr)) {
436  try {
437  getFile(name);
438  return FILE;
439  } catch(...) { }
440  }
441 
442  if (tp == typeid(bool)) {
443  return BOOL;
444  }
445  else if(tp == typeid(int)) {
446  return INT;
447  }
448  else if (tp == typeid(double)) {
449  return DOUBLE;
450  }
451  else if (tp == typeid(string)) {
452  return STRING;
453  }
454  else if (tp == typeid(PropertySet::Ptr)) {
455  return POLICY;
456  }
457  else {
458  throw LSST_EXCEPT
460  string("Policy: illegal type held by PropertySet: ") + tp.name());
461  }
462  } catch (pexExcept::NotFoundError&) {
463  return UNDEF;
464  }
465 }
466 
467 template <> bool Policy::getValue <bool> (const string& name) const {
468  return getBool(name);
469 }
470 template <> int Policy::getValue <int> (const string& name) const {
471  return getInt(name);
472 }
473 template <> double Policy::getValue <double> (const string& name) const {
474  return getDouble(name);
475 }
476 template <> string Policy::getValue <string> (const string& name) const {
477  return getString(name);
478 }
479 template <>
480 Policy::FilePtr Policy::getValue <Policy::FilePtr> (const string& name) const {
481  return getFile(name);
482 }
483 template <>
484 Policy::ConstPtr Policy::getValue <Policy::ConstPtr> (const string& name) const {
485  return getPolicy(name);
486 }
487 
488 template <> vector<bool> Policy::getValueArray<bool>(const string& name) const {
489  return getBoolArray(name);
490 }
491 template <> vector<int> Policy::getValueArray<int>(const string& name) const {
492  return getIntArray(name);
493 }
494 template <> vector<double> Policy::getValueArray<double>(const string& name) const {
495  return getDoubleArray(name);
496 }
497 template <> vector<string> Policy::getValueArray<string>(const string& name) const {
498  return getStringArray(name);
499 }
500 template <> Policy::FilePtrArray Policy::getValueArray<Policy::FilePtr>(const string& name) const {
501  return getFileArray(name);
502 }
503 template <> Policy::PolicyPtrArray Policy::getValueArray<Policy::Ptr>(const string& name) const {
504  return getPolicyArray(name);
505 }
506 template <> Policy::ConstPolicyPtrArray Policy::getValueArray<Policy::ConstPtr>(const string& name) const {
507  return getConstPolicyArray(name);
508 }
509 
510 template <> Policy::ValueType Policy::getValueType<bool>() { return BOOL; }
511 template <> Policy::ValueType Policy::getValueType<int>() { return INT; }
512 template <> Policy::ValueType Policy::getValueType<double>() { return DOUBLE; }
513 template <> Policy::ValueType Policy::getValueType<string>() { return STRING; }
514 template <> Policy::ValueType Policy::getValueType<Policy>() { return POLICY; }
515 template <> Policy::ValueType Policy::getValueType<Policy::FilePtr>() { return FILE; }
516 template <> Policy::ValueType Policy::getValueType<Policy::Ptr>() { return POLICY; }
517 template <> Policy::ValueType Policy::getValueType<Policy::ConstPtr>() { return POLICY; }
518 
519 template <> void Policy::setValue(const string& name, const bool& value) {
520  set(name, value); }
521 template <> void Policy::setValue(const string& name, const int& value) {
522  set(name, value); }
523 template <> void Policy::setValue(const string& name, const double& value) {
524  set(name, value); }
525 template <> void Policy::setValue(const string& name, const string& value) {
526  set(name, value); }
527 template <> void Policy::setValue(const string& name, const Ptr& value) {
528  set(name, value); }
529 template <> void Policy::setValue(const string& name, const FilePtr& value) {
530  set(name, value); }
531 
532 template <> void Policy::addValue(const string& name, const bool& value) {
533  add(name, value); }
534 template <> void Policy::addValue(const string& name, const int& value) {
535  add(name, value); }
536 template <> void Policy::addValue(const string& name, const double& value) {
537  add(name, value); }
538 template <> void Policy::addValue(const string& name, const string& value) {
539  add(name, value); }
540 template <> void Policy::addValue(const string& name, const Ptr& value) {
541  add(name, value); }
542 template <> void Policy::addValue(const string& name, const FilePtr& value) {
543  add(name, value); }
544 
546  ConstPolicyPtrArray out;
547  vector<PropertySet::Ptr> psa = _getPropSetList(name);
549  for(i=psa.begin(); i != psa.end(); ++i)
550  out.push_back(ConstPtr(new Policy(*i)));
551  return out;
552 }
553 
554 Policy::PolicyPtrArray Policy::getPolicyArray(const string& name) const {
555  PolicyPtrArray out;
556  vector<PropertySet::Ptr> psa = _getPropSetList(name);
558  for(i=psa.begin(); i != psa.end(); ++i)
559  out.push_back(Ptr(new Policy(*i)));
560  return out;
561 }
562 
563 Policy::FilePtr Policy::getFile(const string& name) const {
564  FilePtr out =
565  std::dynamic_pointer_cast<PolicyFile>(_data->getAsPersistablePtr(name));
566  if (! out.get())
567  throw LSST_EXCEPT(TypeError, name, string(typeName[FILE]));
568  return out;
569 }
570 
571 Policy::FilePtrArray Policy::getFileArray(const string& name) const
572 {
573  FilePtrArray out;
574  vector<Persistable::Ptr> pfa = _getPersistList(name);
576  FilePtr fp;
577  for(i = pfa.begin(); i != pfa.end(); ++i) {
579  if (! fp.get())
580  throw LSST_EXCEPT(TypeError, name, string(typeName[FILE]));
581  out.push_back(fp);
582  }
583 
584  return out;
585 }
586 
587 void Policy::set(const string& name, const FilePtr& value) {
588  _data->set(name, std::dynamic_pointer_cast<Persistable>(value));
589 }
590 
591 void Policy::add(const string& name, const FilePtr& value) {
592  _data->add(name, std::dynamic_pointer_cast<Persistable>(value));
593 }
594 
611 int Policy::loadPolicyFiles(const fs::path& repository, bool strict) {
612  fs::path repos = repository;
613  int result = 0;
614  if (repos.empty()) repos = ".";
615 
616  // iterate through the top-level names in this Policy
617  list<string> names;
618  fileNames(names, true);
619  for(list<string>::iterator it=names.begin(); it != names.end(); it++) {
620 
621  // iterate through the files in the value array
622  const FilePtrArray& pfiles = getFileArray(*it);
623  PolicyPtrArray pols;
624  pols.reserve(pfiles.size());
625 
626  FilePtrArray::const_iterator pfi;
627  for(pfi=pfiles.begin(); pfi != pfiles.end(); pfi++) {
628  // increment even if fail, since we will remove the file record
629  ++result;
630 
631  Ptr policy = std::make_shared<Policy>();
632  try {
633  fs::path path = (*pfi)->getPath();
634  // if possible, use the policy file's own loading mechanism
635  if (path.is_complete()) {
636  (*pfi)->load(*policy);
637  }
638  else {
639  fs::path localPath = repos / (*pfi)->getPath();
640  PolicyFile(localPath.string()).load(*policy);
641  }
642  }
643  catch (pexExcept::IoError& e) {
644  if (strict) {
645  throw e;
646  }
647  // TODO: log a problem
648  }
649  catch (ParserError& e) {
650  if (strict) {
651  throw e;
652  }
653  // TODO: log a problem
654  }
655  // everything else will get sent up the stack
656 
657  pols.push_back(policy);
658  }
659 
660  remove(*it);
661  for (PolicyPtrArray::iterator pi = pols.begin(); pi != pols.end(); ++pi)
662  add(*it, *pi);
663  }
664 
665  // Now iterate again to recurse into sub-Policy values
666  policyNames(names, true);
667  for(list<string>::iterator it=names.begin(); it != names.end(); it++) {
668  PolicyPtrArray policies = getPolicyArray(*it);
669 
670  // iterate through the Policies in this array
671  PolicyPtrArray::iterator pi;
672  for(pi = policies.begin(); pi != policies.end(); pi++)
673  result += (*pi)->loadPolicyFiles(repos, strict);
674  }
675 
676  return result;
677 }
678 
679 
701 int Policy::mergeDefaults(const Policy& defaultPol, bool keepForValidation,
702  ValidationError *errs)
703 {
704  int added = 0;
705 
706  // if defaultPol is a dictionary, extract the default values
707  auto_ptr<Policy> pol(0);
708  const Policy *def = &defaultPol;
709  if (def->isDictionary()) {
710  // extract default values from dictionary
711  pol.reset(new Policy(false, Dictionary(*def)));
712  def = pol.get();
713  }
714 
715  list<string> params;
716  def->paramNames(params);
718  for(nm = params.begin(); nm != params.end(); ++nm) {
719  if (! exists(*nm)) {
720  const std::type_info& tp = def->getTypeInfo(*nm);
721  if (tp == typeid(bool)) {
722  BoolArray a = def->getBoolArray(*nm);
723  BoolArray::iterator vi;
724  for(vi=a.begin(); vi != a.end(); ++vi)
725  add(*nm, *vi);
726  }
727  else if (tp == typeid(int)) {
728  IntArray a = def->getIntArray(*nm);
729  IntArray::iterator vi;
730  for(vi=a.begin(); vi != a.end(); ++vi)
731  add(*nm, *vi);
732  }
733  else if (tp == typeid(double)) {
734  DoubleArray a = def->getDoubleArray(*nm);
735  DoubleArray::iterator vi;
736  for(vi=a.begin(); vi != a.end(); ++vi)
737  add(*nm, *vi);
738  }
739  else if (tp == typeid(string)) {
740  StringArray a = def->getStringArray(*nm);
741  StringArray::iterator vi;
742  for(vi=a.begin(); vi != a.end(); ++vi)
743  add(*nm, *vi);
744  }
745  else if (def->isFile(*nm)) {
746  FilePtrArray a = def->getFileArray(*nm);
747  FilePtrArray::iterator vi;
748  for(vi=a.begin(); vi != a.end(); ++vi)
749  add(*nm, *vi);
750  }
751  else {
752  // should not happen
754  string("Unknown type for \"") + *nm
755  + "\": \"" + getTypeName(*nm) + "\"");
756  // added--;
757  }
758  added++;
759  }
760  }
761 
762  // if a dictionary is available, validate after all defaults are added
763  // propagate dictionary? If so, look for one and use it to validate
764  if (keepForValidation) {
765  if (defaultPol.isDictionary())
766  setDictionary(Dictionary(defaultPol));
767  else if (defaultPol.canValidate())
768  setDictionary(*defaultPol.getDictionary());
769  // if we couldn't find a dictionary, don't complain -- the API should
770  // work with default values even if defaultPol is a Policy without an
771  // attached Dictionary
772  if (canValidate())
773  getDictionary()->validate(*this, errs);
774  }
775  // don't keep a dictionary around, but validate anyway only if defaultPol is
776  // a Dictionary (if keepForValidation is false, there is a possibility that
777  // we don't want to use the attached Dictionary for validation)
778  else if (defaultPol.isDictionary())
779  Dictionary(defaultPol).validate(*this, errs);
780 
781  return added;
782 }
783 
784 /*
785  * return a string representation of the value given by a name. The
786  * string "<null>" is printed if the name does not exist.
787  */
788 string Policy::str(const string& name, const string& indent) const {
789  ostringstream out;
790 
791  try {
792  const std::type_info& tp = _data->typeOf(name);
793  if (tp == typeid(bool)) {
794  BoolArray b = getBoolArray(name);
795  BoolArray::iterator vi;
796  for(vi=b.begin(); vi != b.end(); ++vi) {
797  out << *vi;
798  if (vi+1 != b.end()) out << ", ";
799  }
800  }
801  else if (tp == typeid(int)) {
802  IntArray i = getIntArray(name);
803  IntArray::iterator vi;
804  for(vi=i.begin(); vi != i.end(); ++vi) {
805  out << *vi;
806  if (vi+1 != i.end()) out << ", ";
807  }
808  }
809  else if (tp == typeid(double)) {
810  DoubleArray d = getDoubleArray(name);
811  DoubleArray::iterator vi;
812  for(vi=d.begin(); vi != d.end(); ++vi) {
813  out << *vi;
814  if (vi+1 != d.end()) out << ", ";
815  }
816  }
817  else if (tp == typeid(string)) {
818  StringArray s = _data->getArray<string>(name);
819  StringArray::iterator vi;
820  for(vi= s.begin(); vi != s.end(); ++vi) {
821  out << '"' << *vi << '"';
822  if (vi+1 != s.end()) out << ", ";
823  }
824  }
825  else if (tp == typeid(PropertySet::Ptr)) {
827  _data->getArray<PropertySet::Ptr>(name);
829  for(vi= p.begin(); vi != p.end(); ++vi) {
830  out << "{\n";
831  Policy(*vi).print(out, "", indent+" ");
832  out << indent << "}";
833  if (vi+1 != p.end()) out << ", ";
834  out.flush();
835  }
836  }
837  else if (tp == typeid(Persistable::Ptr)) {
838  FilePtrArray f = getFileArray(name);
839  FilePtrArray::iterator vi;
840  for(vi= f.begin(); vi != f.end(); ++vi) {
841  out << "FILE:" << (*vi)->getPath();
842  if (vi+1 != f.end()) out << ", ";
843  out.flush();
844  }
845  }
846  else {
848  "Policy: unexpected type held by any");
849  }
850  }
851  catch (NameNotFound&) {
852  out << "<null>";
853  }
854 
855  // out << ends; // unnecessary but problematic, according to #316
856  return out.str();
857 }
858 
859 /*
860  * print the contents of this policy to an output stream
861  */
862 void Policy::print(ostream& out, const string& label,
863  const string& indent) const
864 {
865  list<string> nms;
866  names(nms, true);
867  if (label.size() > 0)
868  out << indent << label << ":\n";
869  for(list<string>::iterator n = nms.begin(); n != nms.end(); ++n) {
870  out << indent << " " << *n << ": " << str(*n, indent+" ") << endl;
871  }
872 }
873 
874 /*
875  * convert the entire contents of this policy to a string. This
876  * is mainly intended for debugging purposes.
877  */
878 string Policy::toString() const {
879  ostringstream os;
880  print(os);
881  return os.str();
882 }
883 
884 //@endcond
885 
886 } // namespace policy
887 } // namespace pex
888 } // namespace lsst
std::shared_ptr< PolicyFile > FilePtr
Definition: Policy.h:176
std::shared_ptr< Policy > Ptr
Definition: Policy.h:172
definition of the PolicySource class
void set(const std::string &name, const Ptr &value)
Set a value with the given name.
Definition: Policy.h:1044
std::vector< Ptr > PolicyPtrArray
Definition: Policy.h:182
static Policy * createPolicyFromUrn(const std::string &urn, bool validate=true)
Create a Policy from a file specified by a URN.
definition of the PolicyFile class
const ConstDictPtr getDictionary() const
The dictionary (if any) that this policy uses to validate itself, including checking set() and add() ...
bool canValidate() const
Can this policy validate itself – that is, does it have a dictionary that it can use to validate its...
STL class.
virtual void load(Policy &policy) const
load the data from this Policy source into a Policy object.
std::shared_ptr< const Dictionary > ConstDictPtr
Definition: Policy.h:175
T endl(T... args)
definition of Policy parsing exceptions
STL namespace.
FilePtrArray getFileArray(const std::string &name) const
return an array of PolicyFile pointers associated with the given name.
void setDictionary(const Dictionary &dict)
Update this policy&#39;s dictionary that it uses to validate itself.
PolicyPtrArray getPolicyArray(const std::string &name) const
return an array of Policy pointers associated with the given name.
void validate(ValidationError *errs=0) const
Validate this policy, using its stored dictionary.
T end(T... args)
static bool looksLikeUrn(const std::string &s, bool strict=false)
Does s look like a URN? That is, does it start with URN_PREFIX or URN_PREFIX_ABBREV?
static const char *const typeName[]
c-string forms for the supported value types.
Definition: Policy.h:205
STL class.
FilePtr getFile(const std::string &name) const
return a PolicyFile (a reference to a file with "sub-Policy" data) identified by a given name...
STL class.
T push_back(T... args)
static FilePtr createPolicyFile(const std::string &pathOrUrn, bool strict=false)
Create a PolicyFile or UrnPolicyFile from pathOrUrn.
bool exists() const
return true if the file exists.
Definition: PolicyFile.h:181
PolicyFile(const std::string &filepath, const SupportedFormats::Ptr &fmts=defaultFormats)
create a Policy file that points a file with given path.
T erase(T... args)
void addValue(const std::string &name, const T &value)
Add a value to an array of values with a given name.
Definition: Policy.h:1214
T str(T... args)
T dynamic_pointer_cast(T... args)
STL class.
void setValue(const std::string &name, const T &value)
Set a value with the given name.
Definition: Policy.h:1203
int mergeDefaults(const Policy &defaultPol, bool keepForValidation=true, ValidationError *errs=0)
use the values found in the given policy as default values for parameters not specified in this polic...
T count(T... args)
T flush(T... args)
T size(T... args)
#define LSST_EXCEPT(type,...)
std::vector< FilePtr > FilePtrArray
Definition: Policy.h:183
STL class.
T name(T... args)
STL class.
Citizen(const std::type_info &)
T begin(T... args)
virtual void print(std::ostream &out, const std::string &label="Policy", const std::string &indent="") const
print the contents of this policy to an output stream.
static ValueType getTypeByName(const std::string &name)
Given the human-readable name of a type ("bool", "int", "policy", etc), what is its ValueType (BOOL...
definition of the Dictionary class
static ValueType getValueType()
A template-ized way to get the ValueType.
Definition: Policy.h:1190
std::shared_ptr< Persistable > Ptr
T transform(T... args)
virtual std::string str(const std::string &name, const std::string &indent="") const
return a string representation of the value given by a name.
int loadPolicyFiles(bool strict=true)
Recursively replace all PolicyFile values with the contents of the files they refer to...
Definition: Policy.h:775
PolicySource(SupportedFormats::Ptr fmts=defaultFormats)
create a Policy file that points a file with given path.
Definition: PolicySource.h:60
ConstPolicyPtrArray getConstPolicyArray(const std::string &name) const
return an array of Policy pointers associated with the given name.
file
STL class.
std::string toString() const
convert the entire contents of this policy to a string.
void add(const std::string &name, const Ptr &value)
Add a value to an array of values with a given name.
Definition: Policy.h:1079
std::shared_ptr< const Policy > ConstPtr
Definition: Policy.h:173
the definition of the UrnPolicyFile class
Policy()
Create an empty policy.
std::vector< ConstPtr > ConstPolicyPtrArray
Definition: Policy.h:184
ValueType
an enumeration for the supported policy types
Definition: Policy.h:189
virtual ~Policy()
destroy this policy