35 #include <boost/filesystem/path.hpp>
44 namespace fs = boost::filesystem;
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())
77 Policy::Policy(
const PolicySource& source)
78 : Citizen(typeid(this)), Persistable(), _data(new PropertySet())
86 Policy::Policy(
const string& pathOrUrn)
87 : Citizen(typeid(this)), Persistable(), _data(new PropertySet())
89 createPolicyFile(pathOrUrn,
true)->load(*
this);
95 Policy::Policy(
const char *pathOrUrn)
96 : Citizen(typeid(this)), Persistable(), _data(new PropertySet())
98 createPolicyFile(pathOrUrn,
true)->load(*
this);
108 Policy::FilePtr Policy::createPolicyFile(
const string& pathOrUrn,
bool strict) {
109 if (UrnPolicyFile::looksLikeUrn(pathOrUrn, strict))
111 return Policy::FilePtr(
new UrnPolicyFile(pathOrUrn));
114 return Policy::FilePtr(
new PolicyFile(pathOrUrn));
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)) {
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);
149 Policy::Policy(
bool validate,
const Dictionary& dict,
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;
171 Policy::Policy(
const Policy& pol)
172 : Citizen(typeid(this)), Persistable(), _data()
174 _data = pol._data->deepCopy();
180 Policy::Policy(Policy& pol,
bool deep)
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);
217 Policy* Policy::createPolicyFromUrn(
const std::string& urn,
bool validate)
221 UrnPolicyFile upf(urn,
true,
true);
222 return _createPolicy(upf,
true, fs::path(),
false);
228 Policy::~Policy() { }
235 bool Policy::canValidate()
const {
236 return static_cast<bool>(_dictionary);
243 const Policy::ConstDictPtr Policy::getDictionary()
const {
252 void Policy::setDictionary(
const Dictionary& dict) {
253 _dictionary = std::make_shared<Dictionary>(dict);
266 void Policy::validate(ValidationError *errs)
const {
267 if (!_dictionary)
throw LSST_EXCEPT(DictionaryError,
"No dictionary set.");
268 else _dictionary->validate(*
this, errs);
276 Policy::ValueType Policy::getTypeByName(
const string& name) {
277 static map<string, Policy::ValueType> nameTypeMap;
279 if (nameTypeMap.size() == 0) {
280 map<string, Policy::ValueType> tmp;
281 int n =
sizeof(Policy::typeName) /
sizeof(
char *);
282 for (
int i = 0; i < n; ++i) {
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;
290 tmp[
"file"] = Policy::FILE;
291 tmp[
"boolean"] = Policy::BOOL;
292 tmp[
"integer"] = Policy::INT;
293 tmp[
"undef"] = Policy::UNDEF;
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);
430 Policy::ValueType Policy::getValueType(
const string& name)
const {
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 {
468 return getBool(name);
470 template <>
int Policy::getValue <int> (
const string& name)
const {
473 template <>
double Policy::getValue <double> (
const string& name)
const {
474 return getDouble(name);
476 template <>
string Policy::getValue <string> (
const string& name)
const {
477 return getString(name);
480 Policy::FilePtr Policy::getValue <Policy::FilePtr> (
const string& name)
const {
481 return getFile(name);
484 Policy::ConstPtr Policy::getValue <Policy::ConstPtr> (
const string& name)
const {
485 return getPolicy(name);
488 template <> vector<bool> Policy::getValueArray<bool>(
const string& name)
const {
489 return getBoolArray(name);
491 template <> vector<int> Policy::getValueArray<int>(
const string& name)
const {
492 return getIntArray(name);
494 template <> vector<double> Policy::getValueArray<double>(
const string& name)
const {
495 return getDoubleArray(name);
497 template <> vector<string> Policy::getValueArray<string>(
const string& name)
const {
498 return getStringArray(name);
500 template <> Policy::FilePtrArray Policy::getValueArray<Policy::FilePtr>(
const string& name)
const {
501 return getFileArray(name);
503 template <> Policy::PolicyPtrArray Policy::getValueArray<Policy::Ptr>(
const string& name)
const {
504 return getPolicyArray(name);
506 template <> Policy::ConstPolicyPtrArray Policy::getValueArray<Policy::ConstPtr>(
const string& name)
const {
507 return getConstPolicyArray(name);
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; }
519 template <>
void Policy::setValue(
const string& name,
const bool& value) {
521 template <>
void Policy::setValue(
const string& name,
const int& value) {
523 template <>
void Policy::setValue(
const string& name,
const double& value) {
525 template <>
void Policy::setValue(
const string& name,
const string& value) {
527 template <>
void Policy::setValue(
const string& name,
const Ptr& value) {
529 template <>
void Policy::setValue(
const string& name,
const FilePtr& value) {
532 template <>
void Policy::addValue(
const string& name,
const bool& value) {
534 template <>
void Policy::addValue(
const string& name,
const int& value) {
536 template <>
void Policy::addValue(
const string& name,
const double& value) {
538 template <>
void Policy::addValue(
const string& name,
const string& value) {
540 template <>
void Policy::addValue(
const string& name,
const Ptr& value) {
542 template <>
void Policy::addValue(
const string& name,
const FilePtr& value) {
545 Policy::ConstPolicyPtrArray Policy::getConstPolicyArray(
const string& name)
const {
546 ConstPolicyPtrArray out;
547 vector<PropertySet::Ptr> psa = _getPropSetList(name);
548 vector<PropertySet::Ptr>::const_iterator i;
549 for(i=psa.begin(); i != psa.end(); ++i)
550 out.push_back(ConstPtr(
new Policy(*i)));
554 Policy::PolicyPtrArray Policy::getPolicyArray(
const string& name)
const {
556 vector<PropertySet::Ptr> psa = _getPropSetList(name);
557 vector<PropertySet::Ptr>::const_iterator i;
558 for(i=psa.begin(); i != psa.end(); ++i)
559 out.push_back(Ptr(
new Policy(*i)));
563 Policy::FilePtr Policy::getFile(
const string& name)
const {
565 std::dynamic_pointer_cast<PolicyFile>(_data->getAsPersistablePtr(name));
567 throw LSST_EXCEPT(TypeError, name,
string(typeName[FILE]));
571 Policy::FilePtrArray Policy::getFileArray(
const string& name)
const
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]));
587 void Policy::set(
const string& name,
const FilePtr& value) {
588 _data->set(name, std::dynamic_pointer_cast<Persistable>(value));
591 void Policy::add(
const string& name,
const FilePtr& value) {
592 _data->add(name, std::dynamic_pointer_cast<Persistable>(value));
611 int Policy::loadPolicyFiles(
const fs::path& repository,
bool strict) {
612 fs::path repos = repository;
614 if (repos.empty()) repos =
".";
618 fileNames(names,
true);
619 for(list<string>::iterator it=names.begin(); it != names.end(); it++) {
622 const FilePtrArray& pfiles = getFileArray(*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)
666 policyNames(names,
true);
667 for(list<string>::iterator it=names.begin(); it != names.end(); it++) {
668 PolicyPtrArray policies = getPolicyArray(*it);
671 PolicyPtrArray::iterator pi;
672 for(pi = policies.begin(); pi != policies.end(); pi++)
673 result += (*pi)->loadPolicyFiles(repos, strict);
701 int Policy::mergeDefaults(
const Policy& defaultPol,
bool keepForValidation,
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)) {
722 BoolArray a = def->getBoolArray(*nm);
723 BoolArray::iterator vi;
724 for(vi=a.begin(); vi != a.end(); ++vi)
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)
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)
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)
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)
753 throw LSST_EXCEPT(pexExcept::LogicError,
754 string(
"Unknown type for \"") + *nm
755 +
"\": \"" + getTypeName(*nm) +
"\"");
764 if (keepForValidation) {
765 if (defaultPol.isDictionary())
766 setDictionary(Dictionary(defaultPol));
767 else if (defaultPol.canValidate())
768 setDictionary(*defaultPol.getDictionary());
773 getDictionary()->validate(*
this, errs);
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)) {
794 BoolArray b = getBoolArray(name);
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)) {
802 IntArray i = getIntArray(name);
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)) {
810 DoubleArray d = getDoubleArray(name);
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)) {
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 <<
", ";
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)) {
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 <<
", ";
847 throw LSST_EXCEPT(pexExcept::LogicError,
848 "Policy: unexpected type held by any");
851 catch (NameNotFound&) {
862 void Policy::print(ostream& out,
const string& label,
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;
878 string Policy::toString()
const {
definition of the PolicySource class
definition of the PolicyFile class
definition of Policy parsing exceptions
definition of the Dictionary class
the definition of the UrnPolicyFile class