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