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"
16 #include "xwalk/application/common/manifest_handlers/permissions_handler.h"
17 #include "xwalk/application/common/manifest_handlers/warp_handler.h"
18 #include "xwalk/application/common/manifest_handlers/widget_handler.h"
21 namespace application {
23 ManifestHandler::~ManifestHandler() {
26 bool ManifestHandler::Validate(scoped_refptr<const ApplicationData> application,
28 std::vector<InstallWarning>* warnings) const {
32 bool ManifestHandler::AlwaysParseForType(Manifest::Type type) const {
36 bool ManifestHandler::AlwaysValidateForType(Manifest::Type type) const {
40 std::vector<std::string> ManifestHandler::PrerequisiteKeys() const {
41 return std::vector<std::string>();
44 ManifestHandlerRegistry* ManifestHandlerRegistry::xpk_registry_ = NULL;
45 ManifestHandlerRegistry* ManifestHandlerRegistry::widget_registry_ = NULL;
47 ManifestHandlerRegistry::ManifestHandlerRegistry(
48 const std::vector<ManifestHandler*>& handlers) {
49 for (std::vector<ManifestHandler*>::const_iterator it = handlers.begin();
50 it != handlers.end(); ++it) {
54 ReorderHandlersGivenDependencies();
57 ManifestHandlerRegistry::~ManifestHandlerRegistry() {
60 ManifestHandlerRegistry*
61 ManifestHandlerRegistry::GetInstance(Manifest::PackageType package_type) {
62 if (package_type == Manifest::TYPE_WGT)
63 return GetInstanceForWGT();
64 return GetInstanceForXPK();
67 ManifestHandlerRegistry*
68 ManifestHandlerRegistry::GetInstanceForWGT() {
70 return widget_registry_;
72 std::vector<ManifestHandler*> handlers;
73 // We can put WGT specific manifest handlers here.
74 handlers.push_back(new WidgetHandler);
75 handlers.push_back(new WARPHandler);
77 handlers.push_back(new CSPHandler(Manifest::TYPE_WGT));
78 handlers.push_back(new NavigationHandler);
79 handlers.push_back(new TizenApplicationHandler);
81 widget_registry_ = new ManifestHandlerRegistry(handlers);
82 return widget_registry_;
85 ManifestHandlerRegistry*
86 ManifestHandlerRegistry::GetInstanceForXPK() {
90 std::vector<ManifestHandler*> handlers;
91 // FIXME: Add manifest handlers here like this:
92 // handlers.push_back(new xxxHandler);
93 handlers.push_back(new CSPHandler(Manifest::TYPE_XPK));
94 handlers.push_back(new MainDocumentHandler);
95 handlers.push_back(new PermissionsHandler);
96 xpk_registry_ = new ManifestHandlerRegistry(handlers);
100 void ManifestHandlerRegistry::Register(ManifestHandler* handler) {
101 const std::vector<std::string>& keys = handler->Keys();
102 for (size_t i = 0; i < keys.size(); ++i) {
103 handlers_[keys[i]] = handler;
107 bool ManifestHandlerRegistry::ParseAppManifest(
108 scoped_refptr<ApplicationData> application, base::string16* error) {
109 std::map<int, ManifestHandler*> handlers_by_order;
110 for (ManifestHandlerMap::iterator iter = handlers_.begin();
111 iter != handlers_.end(); ++iter) {
112 ManifestHandler* handler = iter->second;
113 if (application->GetManifest()->HasPath(iter->first) ||
114 handler->AlwaysParseForType(application->GetType())) {
115 handlers_by_order[order_map_[handler]] = handler;
118 for (std::map<int, ManifestHandler*>::iterator iter =
119 handlers_by_order.begin();
120 iter != handlers_by_order.end(); ++iter) {
121 if (!(iter->second)->Parse(application, error))
127 bool ManifestHandlerRegistry::ValidateAppManifest(
128 scoped_refptr<const ApplicationData> application,
130 std::vector<InstallWarning>* warnings) {
131 for (ManifestHandlerMap::iterator iter = handlers_.begin();
132 iter != handlers_.end(); ++iter) {
133 ManifestHandler* handler = iter->second;
134 if ((application->GetManifest()->HasPath(iter->first) ||
135 handler->AlwaysValidateForType(application->GetType())) &&
136 !handler->Validate(application, error, warnings))
143 void ManifestHandlerRegistry::SetInstanceForTesting(
144 ManifestHandlerRegistry* registry, Manifest::PackageType package_type) {
145 if (package_type == Manifest::TYPE_WGT) {
146 widget_registry_ = registry;
150 xpk_registry_ = registry;
153 void ManifestHandlerRegistry::ReorderHandlersGivenDependencies() {
154 std::set<ManifestHandler*> unsorted_handlers;
155 for (ManifestHandlerMap::const_iterator iter = handlers_.begin();
156 iter != handlers_.end(); ++iter) {
157 unsorted_handlers.insert(iter->second);
162 std::set<ManifestHandler*> next_unsorted_handlers;
163 for (std::set<ManifestHandler*>::const_iterator iter =
164 unsorted_handlers.begin();
165 iter != unsorted_handlers.end(); ++iter) {
166 ManifestHandler* handler = *iter;
167 const std::vector<std::string>& prerequisites =
168 handler->PrerequisiteKeys();
169 int unsatisfied = prerequisites.size();
170 for (size_t i = 0; i < prerequisites.size(); ++i) {
171 ManifestHandlerMap::const_iterator prereq_iter =
172 handlers_.find(prerequisites[i]);
173 CHECK(prereq_iter != handlers_.end())
174 << "Application manifest handler depends on unrecognized key "
176 // Prerequisite is in our map.
177 if (ContainsKey(order_map_, prereq_iter->second))
180 if (unsatisfied == 0) {
181 order_map_[handler] = order;
184 // Put in the list for next time.
185 next_unsorted_handlers.insert(handler);
188 if (next_unsorted_handlers.size() == unsorted_handlers.size())
190 unsorted_handlers.swap(next_unsorted_handlers);
193 // If there are any leftover unsorted handlers, they must have had
194 // circular dependencies.
195 CHECK(unsorted_handlers.empty()) << "Application manifest handlers have "
196 << "circular dependencies!";
199 } // namespace application