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"
12 #include "xwalk/application/common/manifest_handlers/navigation_handler.h"
13 #include "xwalk/application/common/manifest_handlers/tizen_application_handler.h"
14 #include "xwalk/application/common/manifest_handlers/tizen_metadata_handler.h"
15 #include "xwalk/application/common/manifest_handlers/tizen_setting_handler.h"
16 #include "xwalk/application/common/manifest_handlers/tizen_splash_screen_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,
29 std::string* error) const {
33 bool ManifestHandler::AlwaysParseForType(Manifest::Type type) const {
37 bool ManifestHandler::AlwaysValidateForType(Manifest::Type type) const {
41 std::vector<std::string> ManifestHandler::PrerequisiteKeys() const {
42 return std::vector<std::string>();
45 ManifestHandlerRegistry* ManifestHandlerRegistry::xpk_registry_ = NULL;
46 ManifestHandlerRegistry* ManifestHandlerRegistry::widget_registry_ = NULL;
48 ManifestHandlerRegistry::ManifestHandlerRegistry(
49 const std::vector<ManifestHandler*>& handlers) {
50 for (std::vector<ManifestHandler*>::const_iterator it = handlers.begin();
51 it != handlers.end(); ++it) {
55 ReorderHandlersGivenDependencies();
58 ManifestHandlerRegistry::~ManifestHandlerRegistry() {
61 ManifestHandlerRegistry*
62 ManifestHandlerRegistry::GetInstance(Manifest::Type type) {
63 if (type == Manifest::TYPE_WIDGET)
64 return GetInstanceForWGT();
65 return GetInstanceForXPK();
68 ManifestHandlerRegistry*
69 ManifestHandlerRegistry::GetInstanceForWGT() {
71 return widget_registry_;
73 std::vector<ManifestHandler*> handlers;
74 // We can put WGT specific manifest handlers here.
75 handlers.push_back(new WidgetHandler);
76 handlers.push_back(new WARPHandler);
78 handlers.push_back(new CSPHandler(Manifest::TYPE_WIDGET));
79 handlers.push_back(new NavigationHandler);
80 handlers.push_back(new TizenApplicationHandler);
81 handlers.push_back(new TizenSettingHandler);
82 handlers.push_back(new TizenMetaDataHandler);
83 handlers.push_back(new TizenSplashScreenHandler);
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_MANIFEST));
98 handlers.push_back(new PermissionsHandler);
99 xpk_registry_ = new ManifestHandlerRegistry(handlers);
100 return xpk_registry_;
103 void ManifestHandlerRegistry::Register(ManifestHandler* handler) {
104 const std::vector<std::string>& keys = handler->Keys();
105 for (size_t i = 0; i < keys.size(); ++i) {
106 handlers_[keys[i]] = handler;
110 bool ManifestHandlerRegistry::ParseAppManifest(
111 scoped_refptr<ApplicationData> application, base::string16* error) {
112 std::map<int, ManifestHandler*> handlers_by_order;
113 for (ManifestHandlerMap::iterator iter = handlers_.begin();
114 iter != handlers_.end(); ++iter) {
115 ManifestHandler* handler = iter->second;
116 if (application->GetManifest()->HasPath(iter->first) ||
117 handler->AlwaysParseForType(application->manifest_type())) {
118 handlers_by_order[order_map_[handler]] = handler;
121 for (std::map<int, ManifestHandler*>::iterator iter =
122 handlers_by_order.begin();
123 iter != handlers_by_order.end(); ++iter) {
124 if (!(iter->second)->Parse(application, error))
130 bool ManifestHandlerRegistry::ValidateAppManifest(
131 scoped_refptr<const ApplicationData> application,
132 std::string* error) {
133 for (ManifestHandlerMap::iterator iter = handlers_.begin();
134 iter != handlers_.end(); ++iter) {
135 ManifestHandler* handler = iter->second;
136 if ((application->GetManifest()->HasPath(iter->first) ||
137 handler->AlwaysValidateForType(application->manifest_type())) &&
138 !handler->Validate(application, error))
145 void ManifestHandlerRegistry::SetInstanceForTesting(
146 ManifestHandlerRegistry* registry, Manifest::Type type) {
147 if (type == Manifest::TYPE_WIDGET) {
148 widget_registry_ = registry;
152 xpk_registry_ = registry;
155 void ManifestHandlerRegistry::ReorderHandlersGivenDependencies() {
156 std::set<ManifestHandler*> unsorted_handlers;
157 for (ManifestHandlerMap::const_iterator iter = handlers_.begin();
158 iter != handlers_.end(); ++iter) {
159 unsorted_handlers.insert(iter->second);
164 std::set<ManifestHandler*> next_unsorted_handlers;
165 for (std::set<ManifestHandler*>::const_iterator iter =
166 unsorted_handlers.begin();
167 iter != unsorted_handlers.end(); ++iter) {
168 ManifestHandler* handler = *iter;
169 const std::vector<std::string>& prerequisites =
170 handler->PrerequisiteKeys();
171 int unsatisfied = prerequisites.size();
172 for (size_t i = 0; i < prerequisites.size(); ++i) {
173 ManifestHandlerMap::const_iterator prereq_iter =
174 handlers_.find(prerequisites[i]);
175 CHECK(prereq_iter != handlers_.end())
176 << "Application manifest handler depends on unrecognized key "
178 // Prerequisite is in our map.
179 if (ContainsKey(order_map_, prereq_iter->second))
182 if (unsatisfied == 0) {
183 order_map_[handler] = order;
186 // Put in the list for next time.
187 next_unsorted_handlers.insert(handler);
190 if (next_unsorted_handlers.size() == unsorted_handlers.size())
192 unsorted_handlers.swap(next_unsorted_handlers);
195 // If there are any leftover unsorted handlers, they must have had
196 // circular dependencies.
197 CHECK(unsorted_handlers.empty()) << "Application manifest handlers have "
198 << "circular dependencies!";
201 } // namespace application