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"
12 #include "xwalk/application/common/manifest_handlers/permissions_handler.h"
15 namespace application {
17 ManifestHandler::~ManifestHandler() {
20 bool ManifestHandler::Validate(scoped_refptr<const ApplicationData> application,
22 std::vector<InstallWarning>* warnings) const {
26 bool ManifestHandler::AlwaysParseForType(Manifest::Type type) const {
30 bool ManifestHandler::AlwaysValidateForType(Manifest::Type type) const {
34 std::vector<std::string> ManifestHandler::PrerequisiteKeys() const {
35 return std::vector<std::string>();
38 ManifestHandlerRegistry* ManifestHandlerRegistry::registry_ = NULL;
40 ManifestHandlerRegistry::ManifestHandlerRegistry(
41 const std::vector<ManifestHandler*>& handlers) {
42 for (std::vector<ManifestHandler*>::const_iterator it = handlers.begin();
43 it != handlers.end(); ++it) {
47 ReorderHandlersGivenDependencies();
50 ManifestHandlerRegistry::~ManifestHandlerRegistry() {
54 ManifestHandlerRegistry* ManifestHandlerRegistry::GetInstance() {
56 std::vector<ManifestHandler*> handlers;
57 // FIXME: Add manifest handlers here like this:
58 // handlers.push_back(new xxxHandler);
59 handlers.push_back(new CSPHandler);
60 handlers.push_back(new MainDocumentHandler);
61 handlers.push_back(new PermissionsHandler);
63 registry_ = new ManifestHandlerRegistry(handlers);
68 void ManifestHandlerRegistry::Register(ManifestHandler* handler) {
69 const std::vector<std::string>& keys = handler->Keys();
70 for (size_t i = 0; i < keys.size(); ++i) {
71 handlers_[keys[i]] = handler;
75 bool ManifestHandlerRegistry::ParseAppManifest(
76 scoped_refptr<ApplicationData> application, string16* error) {
77 std::map<int, ManifestHandler*> handlers_by_order;
78 for (ManifestHandlerMap::iterator iter = handlers_.begin();
79 iter != handlers_.end(); ++iter) {
80 ManifestHandler* handler = iter->second;
81 if (application->GetManifest()->HasPath(iter->first) ||
82 handler->AlwaysParseForType(application->GetType())) {
83 handlers_by_order[order_map_[handler]] = handler;
86 for (std::map<int, ManifestHandler*>::iterator iter =
87 handlers_by_order.begin();
88 iter != handlers_by_order.end(); ++iter) {
89 if (!(iter->second)->Parse(application, error))
95 bool ManifestHandlerRegistry::ValidateAppManifest(
96 scoped_refptr<const ApplicationData> application,
98 std::vector<InstallWarning>* warnings) {
99 for (ManifestHandlerMap::iterator iter = handlers_.begin();
100 iter != handlers_.end(); ++iter) {
101 ManifestHandler* handler = iter->second;
102 if ((application->GetManifest()->HasPath(iter->first) ||
103 handler->AlwaysValidateForType(application->GetType())) &&
104 !handler->Validate(application, error, warnings))
111 void ManifestHandlerRegistry::SetInstanceForTesting(
112 ManifestHandlerRegistry* registry) {
113 registry_ = registry;
116 void ManifestHandlerRegistry::ReorderHandlersGivenDependencies() {
117 std::set<ManifestHandler*> unsorted_handlers;
118 for (ManifestHandlerMap::const_iterator iter = handlers_.begin();
119 iter != handlers_.end(); ++iter) {
120 unsorted_handlers.insert(iter->second);
125 std::set<ManifestHandler*> next_unsorted_handlers;
126 for (std::set<ManifestHandler*>::const_iterator iter =
127 unsorted_handlers.begin();
128 iter != unsorted_handlers.end(); ++iter) {
129 ManifestHandler* handler = *iter;
130 const std::vector<std::string>& prerequisites =
131 handler->PrerequisiteKeys();
132 int unsatisfied = prerequisites.size();
133 for (size_t i = 0; i < prerequisites.size(); ++i) {
134 ManifestHandlerMap::const_iterator prereq_iter =
135 handlers_.find(prerequisites[i]);
136 CHECK(prereq_iter != handlers_.end())
137 << "Application manifest handler depends on unrecognized key "
139 // Prerequisite is in our map.
140 if (ContainsKey(order_map_, prereq_iter->second))
143 if (unsatisfied == 0) {
144 order_map_[handler] = order;
147 // Put in the list for next time.
148 next_unsorted_handlers.insert(handler);
151 if (next_unsorted_handlers.size() == unsorted_handlers.size())
153 unsorted_handlers.swap(next_unsorted_handlers);
156 // If there are any leftover unsorted handlers, they must have had
157 // circular dependencies.
158 CHECK(unsorted_handlers.empty()) << "Application manifest handlers have "
159 << "circular dependencies!";
162 } // namespace application