Upstream version 6.34.113.0
[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 #if defined(OS_TIZEN)
13 #include "xwalk/application/common/manifest_handlers/navigation_handler.h"
14 #include "xwalk/application/common/manifest_handlers/tizen_application_handler.h"
15 #endif
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"
19
20 namespace xwalk {
21 namespace application {
22
23 ManifestHandler::~ManifestHandler() {
24 }
25
26 bool ManifestHandler::Validate(scoped_refptr<const ApplicationData> application,
27                                std::string* error,
28                                std::vector<InstallWarning>* warnings) const {
29   return true;
30 }
31
32 bool ManifestHandler::AlwaysParseForType(Manifest::Type type) const {
33   return false;
34 }
35
36 bool ManifestHandler::AlwaysValidateForType(Manifest::Type type) const {
37   return false;
38 }
39
40 std::vector<std::string> ManifestHandler::PrerequisiteKeys() const {
41   return std::vector<std::string>();
42 }
43
44 ManifestHandlerRegistry* ManifestHandlerRegistry::xpk_registry_ = NULL;
45 ManifestHandlerRegistry* ManifestHandlerRegistry::widget_registry_ = NULL;
46
47 ManifestHandlerRegistry::ManifestHandlerRegistry(
48     const std::vector<ManifestHandler*>& handlers) {
49   for (std::vector<ManifestHandler*>::const_iterator it = handlers.begin();
50        it != handlers.end(); ++it) {
51     Register(*it);
52   }
53
54   ReorderHandlersGivenDependencies();
55 }
56
57 ManifestHandlerRegistry::~ManifestHandlerRegistry() {
58 }
59
60 ManifestHandlerRegistry*
61 ManifestHandlerRegistry::GetInstance(Manifest::PackageType package_type) {
62   if (package_type == Manifest::TYPE_WGT)
63     return GetInstanceForWGT();
64   return GetInstanceForXPK();
65 }
66
67 ManifestHandlerRegistry*
68 ManifestHandlerRegistry::GetInstanceForWGT() {
69   if (widget_registry_)
70     return widget_registry_;
71
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);
76 #if defined(OS_TIZEN)
77   handlers.push_back(new CSPHandler(Manifest::TYPE_WGT));
78   handlers.push_back(new NavigationHandler);
79   handlers.push_back(new TizenApplicationHandler);
80 #endif
81   widget_registry_ = new ManifestHandlerRegistry(handlers);
82   return widget_registry_;
83 }
84
85 ManifestHandlerRegistry*
86 ManifestHandlerRegistry::GetInstanceForXPK() {
87   if (xpk_registry_)
88     return xpk_registry_;
89
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);
97   return xpk_registry_;
98 }
99
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;
104   }
105 }
106
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;
116     }
117   }
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))
122       return false;
123   }
124   return true;
125 }
126
127 bool ManifestHandlerRegistry::ValidateAppManifest(
128     scoped_refptr<const ApplicationData> application,
129     std::string* error,
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))
137       return false;
138   }
139   return true;
140 }
141
142 // static
143 void ManifestHandlerRegistry::SetInstanceForTesting(
144     ManifestHandlerRegistry* registry, Manifest::PackageType package_type) {
145   if (package_type == Manifest::TYPE_WGT) {
146     widget_registry_ = registry;
147     return;
148   }
149
150   xpk_registry_ = registry;
151 }
152
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);
158   }
159
160   int order = 0;
161   while (true) {
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 "
175             << prerequisites[i];
176         // Prerequisite is in our map.
177         if (ContainsKey(order_map_, prereq_iter->second))
178           unsatisfied--;
179       }
180       if (unsatisfied == 0) {
181         order_map_[handler] = order;
182         order++;
183       } else {
184         // Put in the list for next time.
185         next_unsorted_handlers.insert(handler);
186       }
187     }
188     if (next_unsorted_handlers.size() == unsorted_handlers.size())
189       break;
190     unsorted_handlers.swap(next_unsorted_handlers);
191   }
192
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!";
197 }
198
199 }  // namespace application
200 }  // namespace xwalk