]> git.mxchange.org Git - simgear.git/blob - simgear/package/Package.cxx
LGPL license on package files.
[simgear.git] / simgear / package / Package.cxx
1 // Copyright (C) 2013  James Turner - zakalawe@mac.com
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Library General Public
5 // License as published by the Free Software Foundation; either
6 // version 2 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Library General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
16 //
17
18 #include <simgear/package/Package.hxx>
19
20 #include <cassert>
21 #include <boost/foreach.hpp>
22
23 #include <simgear/debug/logstream.hxx> 
24 #include <simgear/structure/exception.hxx>
25
26 #include <simgear/package/Catalog.hxx>
27 #include <simgear/package/Install.hxx>
28 #include <simgear/package/Root.hxx>
29
30 namespace simgear {
31     
32 namespace pkg {
33
34 Package::Package(const SGPropertyNode* aProps, Catalog* aCatalog) :
35     m_catalog(aCatalog)
36 {
37     initWithProps(aProps);
38 }
39
40 void Package::initWithProps(const SGPropertyNode* aProps)
41 {
42     m_props = const_cast<SGPropertyNode*>(aProps);
43 // cache tag values
44     BOOST_FOREACH(const SGPropertyNode* c, aProps->getChildren("tag")) {
45         m_tags.insert(c->getStringValue());
46     }
47 }
48
49 bool Package::matches(const SGPropertyNode* aFilter) const
50 {
51     int nChildren = aFilter->nChildren();
52     for (int i = 0; i < nChildren; i++) {
53         const SGPropertyNode* c = aFilter->getChild(i);
54         if (strutils::starts_with(c->getName(), "rating-")) {
55             int minRating = c->getIntValue();
56             std::string rname = c->getName() + 7;
57             int ourRating = m_props->getChild("rating")->getIntValue(rname, 0);
58             if (ourRating < minRating) {
59                 return false;
60             }
61         }
62         
63         if (strcmp(c->getName(), "tag") == 0) {
64             std::string tag(c->getStringValue());
65             if (m_tags.find(tag) == m_tags.end()) {
66                 return false;
67             }
68         }
69         
70         SG_LOG(SG_GENERAL, SG_WARN, "unknown filter term:" << c->getName());
71     } // of filter props iteration
72     
73     return true;
74 }
75
76 bool Package::isInstalled() const
77 {
78     SGPath p(m_catalog->installRoot());
79     p.append("Aircraft");
80     p.append(id());
81     
82     // anything to check for? look for a valid revision file?
83     return p.exists();
84 }
85
86 Install* Package::install()
87 {
88     SGPath p(m_catalog->installRoot());
89     p.append("Aircraft");
90     p.append(id());
91     if (p.exists()) {
92         return Install::createFromPath(p, m_catalog);
93     }
94     
95     Install* ins = new Install(this, p);
96     m_catalog->root()->scheduleToUpdate(ins);
97     return ins;
98 }
99
100 std::string Package::id() const
101 {
102     return m_props->getStringValue("id");
103 }
104
105 std::string Package::md5() const
106 {
107     return m_props->getStringValue("md5");
108 }
109
110 unsigned int Package::revision() const
111 {
112     return m_props->getIntValue("revision");
113 }
114     
115 SGPropertyNode* Package::properties() const
116 {
117     return m_props.ptr();
118 }
119
120 string_list Package::thumbnailUrls() const
121 {
122     string_list r;
123     BOOST_FOREACH(SGPropertyNode* dl, m_props->getChildren("thumbnail")) {
124         r.push_back(dl->getStringValue());
125     }
126     return r;
127 }
128
129 string_list Package::downloadUrls() const
130 {
131     string_list r;
132     BOOST_FOREACH(SGPropertyNode* dl, m_props->getChildren("download")) {
133         r.push_back(dl->getStringValue());
134     }
135     return r;
136 }
137
138 std::string Package::getLocalisedProp(const std::string& aName) const
139 {
140     return getLocalisedString(m_props, aName.c_str());
141 }
142
143 std::string Package::getLocalisedString(const SGPropertyNode* aRoot, const char* aName) const
144 {
145     std::string locale = m_catalog->root()->getLocale();
146     if (aRoot->hasChild(locale)) {
147         const SGPropertyNode* localeRoot = aRoot->getChild(locale.c_str());
148         if (localeRoot->hasChild(aName)) {
149             return localeRoot->getStringValue(aName);
150         }
151     }
152     
153     return aRoot->getStringValue(aName);
154 }
155
156 PackageList Package::dependencies() const
157 {
158     PackageList result;
159     
160     BOOST_FOREACH(SGPropertyNode* dep, m_props->getChildren("depends")) {
161         std::string depName = dep->getStringValue("package");
162         unsigned int rev = dep->getIntValue("revision", 0);
163         
164     // prefer local hangar package if possible, in case someone does something
165     // silly with naming. Of course flightgear's aircraft search doesn't know
166     // about hanagrs, so names still need to be unique.
167         Package* depPkg = m_catalog->getPackageById(depName);
168         if (!depPkg) {   
169             Root* rt = m_catalog->root();
170             depPkg = rt->getPackageById(depName);
171             if (!depPkg) {
172                 throw sg_exception("Couldn't satisfy dependency of " + id() + " : " + depName);
173             }
174         }
175         
176         if (depPkg->revision() < rev) {
177             throw sg_range_exception("Couldn't find suitable revision of " + depName);
178         }
179     
180     // forbid recursive dependency graphs, we don't need that level
181     // of complexity for aircraft resources
182         assert(depPkg->dependencies() == PackageList());
183         
184         result.push_back(depPkg);
185     }
186     
187     return result;
188 }
189
190 } // of namespace pkg
191
192 } // of namespace simgear