35 #include <boost/filesystem/path.hpp> 45 namespace pexExcept = lsst::pex::exceptions;
46 namespace dafBase = lsst::daf::base;
54 using dafBase::PropertySet;
55 using dafBase::Persistable;
57 const char *
const Policy::typeName[] = {
71 : Citizen(typeid(this)), Persistable(), _data(new PropertySet())
78 : Citizen(typeid(this)), Persistable(), _data(new PropertySet())
87 : Citizen(typeid(this)), Persistable(), _data(new PropertySet())
89 createPolicyFile(pathOrUrn,
true)->load(*
this);
96 : Citizen(typeid(this)), Persistable(), _data(new PropertySet())
98 createPolicyFile(pathOrUrn,
true)->load(*
this);
118 void extractDefaults(
Policy& target,
const Dictionary& dict, ValidationError& ve) {
120 dict.definedNames(names);
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);
127 if (def->getType() ==
Policy::POLICY && dict.hasSubDictionary(name)) {
129 extractDefaults(*subp, *dict.getSubDictionary(name), ve);
130 if (subp->nameCount() > 0)
131 target.add(name, subp);
150 const fs::path& repository)
151 : Citizen(typeid(this)), Persistable(), _data(new PropertySet())
156 loadedDict = _dictionary;
159 loadedDict.reset(
new Dictionary(dict));
161 loadedDict->loadPolicyFiles(repository,
true);
163 ValidationError ve(LSST_EXCEPT_HERE);
164 extractDefaults(*
this, *loadedDict, ve);
165 if (ve.getParamCount() > 0)
throw ve;
172 : Citizen(typeid(this)), Persistable(), _data()
174 _data = pol._data->deepCopy();
181 : Citizen(typeid(this)), Persistable(), _data()
184 _data = pol._data->deepCopy();
189 Policy* Policy::_createPolicy(PolicySource& source,
bool doIncludes,
190 const fs::path& repository,
bool validate)
192 auto_ptr<Policy> pol(
new Policy());
195 if (pol->isDictionary()) {
197 pol.reset(
new Policy(validate, d, repository));
200 if (doIncludes) pol->loadPolicyFiles(repository,
true);
202 return pol.release();
205 Policy* Policy::_createPolicy(
const string& input,
bool doIncludes,
206 const fs::path& repository,
bool validate)
208 fs::path repos = repository;
210 fs::path filepath(input);
211 if (filepath.has_parent_path()) repos = filepath.parent_path();
213 PolicyFile file(input);
214 return _createPolicy(file, doIncludes, repos, validate);
221 UrnPolicyFile upf(urn,
true,
true);
222 return _createPolicy(upf,
true, fs::path(),
false);
236 return static_cast<bool>(_dictionary);
253 _dictionary = std::make_shared<Dictionary>(dict);
267 if (!_dictionary)
throw LSST_EXCEPT(DictionaryError,
"No dictionary set.");
268 else _dictionary->validate(*
this, errs);
277 static map<string, Policy::ValueType> nameTypeMap;
279 if (nameTypeMap.size() == 0) {
280 map<string, Policy::ValueType> tmp;
282 for (
int i = 0; i < n; ++i) {
285 string lowered(Policy::typeName[i]);
286 transform(lowered.begin(), lowered.end(), lowered.begin(), ::tolower);
297 if (tmp.count(name) == 1)
return tmp[name];
300 if (nameTypeMap.count(name) == 1)
return nameTypeMap[name];
302 throw LSST_EXCEPT(BadNameError, name);
319 int Policy::_names(vector<string>& names,
320 bool topLevelOnly,
bool append,
int want)
const 322 bool shouldCheck =
true;
324 int have = 0, count = 0;
326 src = _data->propertySetNames(topLevelOnly);
331 src = _data->names(topLevelOnly);
333 src = _data->paramNames(topLevelOnly);
335 if (!append) names.erase(names.begin(), names.end());
337 StringArray::iterator i;
338 for(i = src.begin(); i != src.end(); ++i) {
347 if ((have&want) > 0) {
370 int Policy::_names(list<string>& names,
371 bool topLevelOnly,
bool append,
int want)
const 373 bool shouldCheck =
true;
375 int have = 0, count = 0;
377 src = _data->propertySetNames(topLevelOnly);
382 src = _data->names(topLevelOnly);
384 src = _data->paramNames(topLevelOnly);
386 if (!append) names.erase(names.begin(), names.end());
388 StringArray::iterator i;
389 for(i = src.begin(); i != src.end(); ++i) {
398 if ((have&want) > 0) {
407 template <
class T>
void Policy::_validate(
const std::string& name,
const T& value,
int curCount) {
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);
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);
432 const std::type_info& tp = _data->typeOf(name);
435 if (tp ==
typeid(Persistable::Ptr)) {
442 if (tp ==
typeid(
bool)) {
445 else if(tp ==
typeid(
int)) {
448 else if (tp ==
typeid(
double)) {
451 else if (tp ==
typeid(
string)) {
454 else if (tp ==
typeid(PropertySet::Ptr)) {
459 (pexExcept::LogicError,
460 string(
"Policy: illegal type held by PropertySet: ") + tp.name());
462 }
catch (pexExcept::NotFoundError&) {
467 template <>
bool Policy::getValue <bool> (
const string& name)
const {
470 template <>
int Policy::getValue <int> (
const string& name)
const {
473 template <>
double Policy::getValue <double> (
const string& name)
const {
476 template <>
string Policy::getValue <string> (
const string& name)
const {
480 Policy::FilePtr Policy::getValue <Policy::FilePtr> (
const string& name)
const {
484 Policy::ConstPtr Policy::getValue <Policy::ConstPtr> (
const string& name)
const {
488 template <> vector<bool> Policy::getValueArray<bool>(
const string& name)
const {
491 template <> vector<int> Policy::getValueArray<int>(
const string& name)
const {
494 template <> vector<double> Policy::getValueArray<double>(
const string& name)
const {
497 template <> vector<string> Policy::getValueArray<string>(
const string& name)
const {
500 template <>
Policy::FilePtrArray Policy::getValueArray<Policy::FilePtr>(
const string& name)
const {
523 template <>
void Policy::setValue(
const string& name,
const double& value) {
525 template <>
void Policy::setValue(
const string& name,
const string& value) {
536 template <>
void Policy::addValue(
const string& name,
const double& value) {
538 template <>
void Policy::addValue(
const string& name,
const string& value) {
547 vector<PropertySet::Ptr> psa = _getPropSetList(name);
548 vector<PropertySet::Ptr>::const_iterator i;
549 for(i=psa.begin(); i != psa.end(); ++i)
556 vector<PropertySet::Ptr> psa = _getPropSetList(name);
557 vector<PropertySet::Ptr>::const_iterator i;
558 for(i=psa.begin(); i != psa.end(); ++i)
565 std::dynamic_pointer_cast<PolicyFile>(_data->getAsPersistablePtr(name));
567 throw LSST_EXCEPT(TypeError, name,
string(
typeName[
FILE]));
574 vector<Persistable::Ptr> pfa = _getPersistList(name);
575 vector<Persistable::Ptr>::const_iterator i;
577 for(i = pfa.begin(); i != pfa.end(); ++i) {
578 fp = std::dynamic_pointer_cast<PolicyFile>(*i);
580 throw LSST_EXCEPT(TypeError, name,
string(
typeName[
FILE]));
588 _data->set(name, std::dynamic_pointer_cast<Persistable>(value));
592 _data->add(name, std::dynamic_pointer_cast<Persistable>(value));
612 fs::path repos = repository;
614 if (repos.empty()) repos =
".";
619 for(list<string>::iterator it=names.begin(); it != names.end(); it++) {
624 pols.reserve(pfiles.size());
626 FilePtrArray::const_iterator pfi;
627 for(pfi=pfiles.begin(); pfi != pfiles.end(); pfi++) {
631 Ptr policy = std::make_shared<Policy>();
633 fs::path path = (*pfi)->getPath();
635 if (path.is_complete()) {
636 (*pfi)->load(*policy);
639 fs::path localPath = repos / (*pfi)->getPath();
640 PolicyFile(localPath.string()).load(*policy);
643 catch (pexExcept::IoError& e) {
649 catch (ParserError& e) {
657 pols.push_back(policy);
661 for (PolicyPtrArray::iterator pi = pols.begin(); pi != pols.end(); ++pi)
667 for(list<string>::iterator it=names.begin(); it != names.end(); it++) {
671 PolicyPtrArray::iterator pi;
672 for(pi = policies.begin(); pi != policies.end(); pi++)
673 result += (*pi)->loadPolicyFiles(repos, strict);
702 ValidationError *errs)
707 auto_ptr<Policy> pol(0);
708 const Policy *def = &defaultPol;
709 if (def->isDictionary()) {
711 pol.reset(
new Policy(
false, Dictionary(*def)));
716 def->paramNames(params);
717 list<string>::iterator nm;
718 for(nm = params.begin(); nm != params.end(); ++nm) {
720 const std::type_info& tp = def->getTypeInfo(*nm);
721 if (tp ==
typeid(
bool)) {
723 BoolArray::iterator vi;
724 for(vi=a.begin(); vi != a.end(); ++vi)
727 else if (tp ==
typeid(
int)) {
729 IntArray::iterator vi;
730 for(vi=a.begin(); vi != a.end(); ++vi)
733 else if (tp ==
typeid(
double)) {
735 DoubleArray::iterator vi;
736 for(vi=a.begin(); vi != a.end(); ++vi)
739 else if (tp ==
typeid(
string)) {
741 StringArray::iterator vi;
742 for(vi=a.begin(); vi != a.end(); ++vi)
745 else if (def->isFile(*nm)) {
747 FilePtrArray::iterator vi;
748 for(vi=a.begin(); vi != a.end(); ++vi)
753 throw LSST_EXCEPT(pexExcept::LogicError,
754 string(
"Unknown type for \"") + *nm
764 if (keepForValidation) {
765 if (defaultPol.isDictionary())
767 else if (defaultPol.canValidate())
778 else if (defaultPol.isDictionary())
779 Dictionary(defaultPol).validate(*
this, errs);
788 string Policy::str(
const string& name,
const string& indent)
const {
792 const std::type_info& tp = _data->typeOf(name);
793 if (tp ==
typeid(
bool)) {
795 BoolArray::iterator vi;
796 for(vi=b.begin(); vi != b.end(); ++vi) {
798 if (vi+1 != b.end()) out <<
", ";
801 else if (tp ==
typeid(
int)) {
803 IntArray::iterator vi;
804 for(vi=i.begin(); vi != i.end(); ++vi) {
806 if (vi+1 != i.end()) out <<
", ";
809 else if (tp ==
typeid(
double)) {
811 DoubleArray::iterator vi;
812 for(vi=d.begin(); vi != d.end(); ++vi) {
814 if (vi+1 != d.end()) out <<
", ";
817 else if (tp ==
typeid(
string)) {
819 StringArray::iterator vi;
820 for(vi= s.begin(); vi != s.end(); ++vi) {
821 out <<
'"' << *vi <<
'"';
822 if (vi+1 != s.end()) out <<
", ";
825 else if (tp ==
typeid(PropertySet::Ptr)) {
826 vector<PropertySet::Ptr> p =
827 _data->getArray<PropertySet::Ptr>(name);
828 vector<PropertySet::Ptr>::iterator vi;
829 for(vi= p.begin(); vi != p.end(); ++vi) {
831 Policy(*vi).print(out,
"", indent+
" ");
832 out << indent <<
"}";
833 if (vi+1 != p.end()) out <<
", ";
837 else if (tp ==
typeid(Persistable::Ptr)) {
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 <<
", ";
847 throw LSST_EXCEPT(pexExcept::LogicError,
848 "Policy: unexpected type held by any");
851 catch (NameNotFound&) {
863 const string& indent)
const 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;
std::vector< int > IntArray
std::shared_ptr< PolicyFile > FilePtr
std::shared_ptr< Policy > Ptr
definition of the PolicySource class
void set(const std::string &name, const Ptr &value)
Set a value with the given name.
std::vector< Ptr > PolicyPtrArray
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...
int policyNames(std::list< std::string > &names, bool topLevelOnly=false, bool append=false) const
load the names of parameters into a given list.
std::shared_ptr< const Dictionary > ConstDictPtr
definition of Policy parsing exceptions
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'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.
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.
bool isFile(const std::string &name) const
return true if the value pointed to by the given name is a PolicyFile
DoubleArray getDoubleArray(const std::string &name) const
return an array of values associated with the given name
FilePtr getFile(const std::string &name) const
return a PolicyFile (a reference to a file with "sub-Policy" data) identified by a given name...
StringArray getStringArray(const std::string &name) const
return an array of values associated with the given name
bool getBool(const std::string &name) const
return a boolean value associated with the given name.
static FilePtr createPolicyFile(const std::string &pathOrUrn, bool strict=false)
Create a PolicyFile or UrnPolicyFile from pathOrUrn.
bool exists(const std::string &name) const
return true if a value exists in this policy for the given name.
std::vector< std::string > StringArray
ConstPtr getPolicy(const std::string &name) const
return a "sub-Policy" identified by a given name.
int getInt(const std::string &name) const
return an integer value associated with the given name.
int fileNames(std::list< std::string > &names, bool topLevelOnly=false, bool append=false) const
load the names of parameters into a given list.
void addValue(const std::string &name, const T &value)
Add a value to an array of values with a given name.
const std::string getString(const std::string &name) const
return a string value associated with the given name .
void setValue(const std::string &name, const T &value)
Set a value with the given name.
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...
bool isPolicy(const std::string &name) const
return true if the value pointed to by the given name is a Policy
double getDouble(const std::string &name) const
return a double value associated with the given name.
BoolArray getBoolArray(const std::string &name) const
return an array of values associated with the given name
std::vector< FilePtr > FilePtrArray
const char * getTypeName(const std::string &name) const
return a string name for the type associated with the parameter of a given name.
int names(std::list< std::string > &names, bool topLevelOnly=false, bool append=false) const
load the names of parameters into a given list.
std::vector< double > DoubleArray
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.
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...
std::vector< bool > BoolArray
ConstPolicyPtrArray getConstPolicyArray(const std::string &name) const
return an array of Policy pointers associated with the given name.
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.
std::shared_ptr< const Policy > ConstPtr
the definition of the UrnPolicyFile class
IntArray getIntArray(const std::string &name) const
return an array of values associated with the given name
Policy()
Create an empty policy.
std::vector< ConstPtr > ConstPolicyPtrArray
ValueType
an enumeration for the supported policy types
virtual ~Policy()
destroy this policy