- add third_party src.
[platform/framework/web/crosswalk.git] / src / xwalk / application / common / manifest_handler.cc
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.
4
5 #include "xwalk/application/common/manifest_handler.h"
6
7 #include <set>
8
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"
13
14 namespace xwalk {
15 namespace application {
16
17 ManifestHandler::~ManifestHandler() {
18 }
19
20 bool ManifestHandler::Validate(scoped_refptr<const ApplicationData> application,
21                                std::string* error,
22                                std::vector<InstallWarning>* warnings) const {
23   return true;
24 }
25
26 bool ManifestHandler::AlwaysParseForType(Manifest::Type type) const {
27   return false;
28 }
29
30 bool ManifestHandler::AlwaysValidateForType(Manifest::Type type) const {
31   return false;
32 }
33
34 std::vector<std::string> ManifestHandler::PrerequisiteKeys() const {
35   return std::vector<std::string>();
36 }
37
38 ManifestHandlerRegistry* ManifestHandlerRegistry::registry_ = NULL;
39
40 ManifestHandlerRegistry::ManifestHandlerRegistry(
41     const std::vector<ManifestHandler*>& handlers) {
42   for (std::vector<ManifestHandler*>::const_iterator it = handlers.begin();
43        it != handlers.end(); ++it) {
44     Register(*it);
45   }
46
47   ReorderHandlersGivenDependencies();
48 }
49
50 ManifestHandlerRegistry::~ManifestHandlerRegistry() {
51 }
52
53 // static
54 ManifestHandlerRegistry* ManifestHandlerRegistry::GetInstance() {
55   if (!registry_) {
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);
62
63     registry_ = new ManifestHandlerRegistry(handlers);
64   }
65   return registry_;
66 }
67
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;
72   }
73 }
74
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;
84     }
85   }
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))
90       return false;
91   }
92   return true;
93 }
94
95 bool ManifestHandlerRegistry::ValidateAppManifest(
96     scoped_refptr<const ApplicationData> application,
97     std::string* error,
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))
105       return false;
106   }
107   return true;
108 }
109
110 // static
111 void ManifestHandlerRegistry::SetInstanceForTesting(
112     ManifestHandlerRegistry* registry) {
113     registry_ = registry;
114 }
115
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);
121   }
122
123   int order = 0;
124   while (true) {
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 "
138             << prerequisites[i];
139         // Prerequisite is in our map.
140         if (ContainsKey(order_map_, prereq_iter->second))
141           unsatisfied--;
142       }
143       if (unsatisfied == 0) {
144         order_map_[handler] = order;
145         order++;
146       } else {
147         // Put in the list for next time.
148         next_unsorted_handlers.insert(handler);
149       }
150     }
151     if (next_unsorted_handlers.size() == unsorted_handlers.size())
152       break;
153     unsorted_handlers.swap(next_unsorted_handlers);
154   }
155
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!";
160 }
161
162 }  // namespace application
163 }  // namespace xwalk