]> git.mxchange.org Git - simgear.git/blob - simgear/package/Package.cxx
b866879e6c99a1fe469c7a228a529261f5dfac41
[simgear.git] / simgear / package / Package.cxx
1
2
3 #include <simgear/package/Package.hxx>
4
5 #include <cassert>
6 #include <boost/foreach.hpp>
7
8 #include <simgear/debug/logstream.hxx> 
9 #include <simgear/structure/exception.hxx>
10
11 #include <simgear/package/Catalog.hxx>
12 #include <simgear/package/Install.hxx>
13 #include <simgear/package/Root.hxx>
14
15 namespace simgear {
16     
17 namespace pkg {
18
19 Package::Package(const SGPropertyNode* aProps, Catalog* aCatalog) :
20     m_catalog(aCatalog)
21 {
22     initWithProps(aProps);
23 }
24
25 void Package::initWithProps(const SGPropertyNode* aProps)
26 {
27     m_props = const_cast<SGPropertyNode*>(aProps);
28 // cache tag values
29     BOOST_FOREACH(const SGPropertyNode* c, aProps->getChildren("tag")) {
30         m_tags.insert(c->getStringValue());
31     }
32 }
33
34 bool Package::matches(const SGPropertyNode* aFilter) const
35 {
36     int nChildren = aFilter->nChildren();
37     for (int i = 0; i < nChildren; i++) {
38         const SGPropertyNode* c = aFilter->getChild(i);
39         if (strutils::starts_with(c->getName(), "rating-")) {
40             int minRating = c->getIntValue();
41             std::string rname = c->getName() + 7;
42             int ourRating = m_props->getChild("rating")->getIntValue(rname, 0);
43             if (ourRating < minRating) {
44                 return false;
45             }
46         }
47         
48         if (strcmp(c->getName(), "tag") == 0) {
49             std::string tag(c->getStringValue());
50             if (m_tags.find(tag) == m_tags.end()) {
51                 return false;
52             }
53         }
54         
55         SG_LOG(SG_GENERAL, SG_WARN, "unknown filter term:" << c->getName());
56     } // of filter props iteration
57     
58     return true;
59 }
60
61 bool Package::isInstalled() const
62 {
63     SGPath p(m_catalog->installRoot());
64     p.append("Aircraft");
65     p.append(id());
66     
67     // anything to check for? look for a valid revision file?
68     return p.exists();
69 }
70
71 Install* Package::install()
72 {
73     SGPath p(m_catalog->installRoot());
74     p.append("Aircraft");
75     p.append(id());
76     if (p.exists()) {
77         return Install::createFromPath(p, m_catalog);
78     }
79     
80     Install* ins = new Install(this, p);
81     m_catalog->root()->scheduleToUpdate(ins);
82     return ins;
83 }
84
85 std::string Package::id() const
86 {
87     return m_props->getStringValue("id");
88 }
89
90 std::string Package::md5() const
91 {
92     return m_props->getStringValue("md5");
93 }
94
95 unsigned int Package::revision() const
96 {
97     return m_props->getIntValue("revision");
98 }
99     
100 SGPropertyNode* Package::properties() const
101 {
102     return m_props.ptr();
103 }
104
105 string_list Package::thumbnailUrls() const
106 {
107     string_list r;
108     BOOST_FOREACH(SGPropertyNode* dl, m_props->getChildren("thumbnail")) {
109         r.push_back(dl->getStringValue());
110     }
111     return r;
112 }
113
114 string_list Package::downloadUrls() const
115 {
116     string_list r;
117     BOOST_FOREACH(SGPropertyNode* dl, m_props->getChildren("download")) {
118         r.push_back(dl->getStringValue());
119     }
120     return r;
121 }
122
123 std::string Package::getLocalisedProp(const std::string& aName) const
124 {
125     return getLocalisedString(m_props, aName.c_str());
126 }
127
128 std::string Package::getLocalisedString(const SGPropertyNode* aRoot, const char* aName) const
129 {
130     std::string locale = m_catalog->root()->getLocale();
131     if (aRoot->hasChild(locale)) {
132         const SGPropertyNode* localeRoot = aRoot->getChild(locale.c_str());
133         if (localeRoot->hasChild(aName)) {
134             return localeRoot->getStringValue(aName);
135         }
136     }
137     
138     return aRoot->getStringValue(aName);
139 }
140
141 PackageList Package::dependencies() const
142 {
143     PackageList result;
144     
145     BOOST_FOREACH(SGPropertyNode* dep, m_props->getChildren("depends")) {
146         std::string depName = dep->getStringValue("package");
147         unsigned int rev = dep->getIntValue("revision", 0);
148         
149     // prefer local hangar package if possible, in case someone does something
150     // silly with naming. Of course flightgear's aircraft search doesn't know
151     // about hanagrs, so names still need to be unique.
152         Package* depPkg = m_catalog->getPackageById(depName);
153         if (!depPkg) {   
154             Root* rt = m_catalog->root();
155             depPkg = rt->getPackageById(depName);
156             if (!depPkg) {
157                 throw sg_exception("Couldn't satisfy dependency of " + id() + " : " + depName);
158             }
159         }
160         
161         if (depPkg->revision() < rev) {
162             throw sg_range_exception("Couldn't find suitable revision of " + depName);
163         }
164     
165     // forbid recursive dependency graphs, we don't need that level
166     // of complexity for aircraft resources
167         assert(depPkg->dependencies() == PackageList());
168         
169         result.push_back(depPkg);
170     }
171     
172     return result;
173 }
174
175 } // of namespace pkg
176
177 } // of namespace simgear