1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "xwalk/application/common/manifest_handler.h"
9 #include "base/stl_util.h"
10 #include "xwalk/application/common/manifest_handlers/csp_handler.h"
11 #include "xwalk/application/common/manifest_handlers/main_document_handler.h"
13 #include "xwalk/application/common/manifest_handlers/navigation_handler.h"
14 #include "xwalk/application/common/manifest_handlers/tizen_application_handler.h"
15 #include "xwalk/application/common/manifest_handlers/tizen_metadata_handler.h"
16 #include "xwalk/application/common/manifest_handlers/tizen_setting_handler.h"
18 #include "xwalk/application/common/manifest_handlers/permissions_handler.h"
19 #include "xwalk/application/common/manifest_handlers/warp_handler.h"
20 #include "xwalk/application/common/manifest_handlers/widget_handler.h"
23 namespace application {
25 ManifestHandler::~ManifestHandler() {
28 bool ManifestHandler::Validate(scoped_refptr<const ApplicationData> application,
30 std::vector<InstallWarning>* warnings) const {
34 bool ManifestHandler::AlwaysParseForType(Manifest::Type type) const {
38 bool ManifestHandler::AlwaysValidateForType(Manifest::Type type) const {
42 std::vector<std::string> ManifestHandler::PrerequisiteKeys() const {
43 return std::vector<std::string>();
46 ManifestHandlerRegistry* ManifestHandlerRegistry::xpk_registry_ = NULL;
47 ManifestHandlerRegistry* ManifestHandlerRegistry::widget_registry_ = NULL;
49 ManifestHandlerRegistry::ManifestHandlerRegistry(
50 const std::vector<ManifestHandler*>& handlers) {
51 for (std::vector<ManifestHandler*>::const_iterator it = handlers.begin();
52 it != handlers.end(); ++it) {
56 ReorderHandlersGivenDependencies();
59 ManifestHandlerRegistry::~ManifestHandlerRegistry() {
62 ManifestHandlerRegistry*
63 ManifestHandlerRegistry::GetInstance(Manifest::PackageType package_type) {
64 if (package_type == Manifest::TYPE_WGT)
65 return GetInstanceForWGT();
66 return GetInstanceForXPK();
69 ManifestHandlerRegistry*
70 ManifestHandlerRegistry::GetInstanceForWGT() {
72 return widget_registry_;
74 std::vector<ManifestHandler*> handlers;
75 // We can put WGT specific manifest handlers here.
76 handlers.push_back(new WidgetHandler);
77 handlers.push_back(new WARPHandler);
79 handlers.push_back(new CSPHandler(Manifest::TYPE_WGT));
80 handlers.push_back(new NavigationHandler);
81 handlers.push_back(new TizenApplicationHandler);
82 handlers.push_back(new TizenSettingHandler);
83 handlers.push_back(new TizenMetaDataHandler);
85 widget_registry_ = new ManifestHandlerRegistry(handlers);
86 return widget_registry_;
89 ManifestHandlerRegistry*
90 ManifestHandlerRegistry::GetInstanceForXPK() {
94 std::vector<ManifestHandler*> handlers;
95 // FIXME: Add manifest handlers here like this:
96 // handlers.push_back(new xxxHandler);
97 handlers.push_back(new CSPHandler(Manifest::TYPE_XPK));
98 handlers.push_back(new MainDocumentHandler);
99 handlers.push_back(new PermissionsHandler);
100 xpk_registry_ = new ManifestHandlerRegistry(handlers);
101 return xpk_registry_;
104 void ManifestHandlerRegistry::Register(ManifestHandler* handler) {
105 const std::vector<std::string>& keys = handler->Keys();
106 for (size_t i = 0; i < keys.size(); ++i) {
107 handlers_[keys[i]] = handler;
111 bool ManifestHandlerRegistry::ParseAppManifest(
112 scoped_refptr<ApplicationData> application, base::string16* error) {
113 std::map<int, ManifestHandler*> handlers_by_order;
114 for (ManifestHandlerMap::iterator iter = handlers_.begin();
115 iter != handlers_.end(); ++iter) {
116 ManifestHandler* handler = iter->second;
117 if (application->GetManifest()->HasPath(iter->first) ||
118 handler->AlwaysParseForType(application->GetType())) {
119 handlers_by_order[order_map_[handler]] = handler;
122 for (std::map<int, ManifestHandler*>::iterator iter =
123 handlers_by_order.begin();
124 iter != handlers_by_order.end(); ++iter) {
125 if (!(iter->second)->Parse(application, error))
131 bool ManifestHandlerRegistry::ValidateAppManifest(
132 scoped_refptr<const ApplicationData> application,
134 std::vector<InstallWarning>* warnings) {
135 for (ManifestHandlerMap::iterator iter = handlers_.begin();
136 iter != handlers_.end(); ++iter) {
137 ManifestHandler* handler = iter->second;
138 if ((application->GetManifest()->HasPath(iter->first) ||
139 handler->AlwaysValidateForType(application->GetType())) &&
140 !handler->Validate(application, error, warnings))
147 void ManifestHandlerRegistry::SetInstanceForTesting(
148 ManifestHandlerRegistry* registry, Manifest::PackageType package_type) {
149 if (package_type == Manifest::TYPE_WGT) {
150 widget_registry_ = registry;
154 xpk_registry_ = registry;
157 void ManifestHandlerRegistry::ReorderHandlersGivenDependencies() {
158 std::set<ManifestHandler*> unsorted_handlers;
159 for (ManifestHandlerMap::const_iterator iter = handlers_.begin();
160 iter != handlers_.end(); ++iter) {
161 unsorted_handlers.insert(iter->second);
166 std::set<ManifestHandler*> next_unsorted_handlers;
167 for (std::set<ManifestHandler*>::const_iterator iter =
168 unsorted_handlers.begin();
169 iter != unsorted_handlers.end(); ++iter) {
170 ManifestHandler* handler = *iter;
171 const std::vector<std::string>& prerequisites =
172 handler->PrerequisiteKeys();
173 int unsatisfied = prerequisites.size();
174 for (size_t i = 0; i < prerequisites.size(); ++i) {
175 ManifestHandlerMap::const_iterator prereq_iter =
176 handlers_.find(prerequisites[i]);
177 CHECK(prereq_iter != handlers_.end())
178 << "Application manifest handler depends on unrecognized key "
180 // Prerequisite is in our map.
181 if (ContainsKey(order_map_, prereq_iter->second))
184 if (unsatisfied == 0) {
185 order_map_[handler] = order;
188 // Put in the list for next time.
189 next_unsorted_handlers.insert(handler);
192 if (next_unsorted_handlers.size() == unsorted_handlers.size())
194 unsorted_handlers.swap(next_unsorted_handlers);
197 // If there are any leftover unsorted handlers, they must have had
198 // circular dependencies.
199 CHECK(unsorted_handlers.empty()) << "Application manifest handlers have "
200 << "circular dependencies!";
203 } // namespace application