7b364d44f41c862df091e17c7d115148e194a681
[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 #if defined(OS_TIZEN)
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 #endif
17 #include "xwalk/application/common/manifest_handlers/permissions_handler.h"
18 #include "xwalk/application/common/manifest_handlers/warp_handler.h"
19 #include "xwalk/application/common/manifest_handlers/widget_handler.h"
20
21 namespace xwalk {
22 namespace application {
23
24 ManifestHandler::~ManifestHandler() {
25 }
26
27 bool ManifestHandler::Validate(scoped_refptr<const ApplicationData> application,
28                                std::string* error,
29                                std::vector<InstallWarning>* warnings) const {
30   return true;
31 }
32
33 bool ManifestHandler::AlwaysParseForType(Manifest::Type type) const {
34   return false;
35 }
36
37 bool ManifestHandler::AlwaysValidateForType(Manifest::Type type) const {
38   return false;
39 }
40
41 std::vector<std::string> ManifestHandler::PrerequisiteKeys() const {
42   return std::vector<std::string>();
43 }
44
45 ManifestHandlerRegistry* ManifestHandlerRegistry::xpk_registry_ = NULL;
46 ManifestHandlerRegistry* ManifestHandlerRegistry::widget_registry_ = NULL;
47
48 ManifestHandlerRegistry::ManifestHandlerRegistry(
49     const std::vector<ManifestHandler*>& handlers) {
50   for (std::vector<ManifestHandler*>::const_iterator it = handlers.begin();
51        it != handlers.end(); ++it) {
52     Register(*it);
53   }
54
55   ReorderHandlersGivenDependencies();
56 }
57
58 ManifestHandlerRegistry::~ManifestHandlerRegistry() {
59 }
60
61 ManifestHandlerRegistry*
62 ManifestHandlerRegistry::GetInstance(Manifest::PackageType package_type) {
63   if (package_type == Manifest::TYPE_WGT)
64     return GetInstanceForWGT();
65   return GetInstanceForXPK();
66 }
67
68 ManifestHandlerRegistry*
69 ManifestHandlerRegistry::GetInstanceForWGT() {
70   if (widget_registry_)
71     return widget_registry_;
72
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);
77 #if defined(OS_TIZEN)
78   handlers.push_back(new CSPHandler(Manifest::TYPE_WGT));
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 #endif
84   widget_registry_ = new ManifestHandlerRegistry(handlers);
85   return widget_registry_;
86 }
87
88 ManifestHandlerRegistry*
89 ManifestHandlerRegistry::GetInstanceForXPK() {
90   if (xpk_registry_)
91     return xpk_registry_;
92
93   std::vector<ManifestHandler*> handlers;
94   // FIXME: Add manifest handlers here like this:
95   // handlers.push_back(new xxxHandler);
96   handlers.push_back(new CSPHandler(Manifest::TYPE_XPK));
97   handlers.push_back(new PermissionsHandler);
98   xpk_registry_ = new ManifestHandlerRegistry(handlers);
99   return xpk_registry_;
100 }
101
102 void ManifestHandlerRegistry::Register(ManifestHandler* handler) {
103   const std::vector<std::string>& keys = handler->Keys();
104   for (size_t i = 0; i < keys.size(); ++i) {
105     handlers_[keys[i]] = handler;
106   }
107 }
108
109 bool ManifestHandlerRegistry::ParseAppManifest(
110     scoped_refptr<ApplicationData> application, base::string16* error) {
111   std::map<int, ManifestHandler*> handlers_by_order;
112   for (ManifestHandlerMap::iterator iter = handlers_.begin();
113        iter != handlers_.end(); ++iter) {
114     ManifestHandler* handler = iter->second;
115     if (application->GetManifest()->HasPath(iter->first) ||
116         handler->AlwaysParseForType(application->GetType())) {
117       handlers_by_order[order_map_[handler]] = handler;
118     }
119   }
120   for (std::map<int, ManifestHandler*>::iterator iter =
121            handlers_by_order.begin();
122        iter != handlers_by_order.end(); ++iter) {
123     if (!(iter->second)->Parse(application, error))
124       return false;
125   }
126   return true;
127 }
128
129 bool ManifestHandlerRegistry::ValidateAppManifest(
130     scoped_refptr<const ApplicationData> application,
131     std::string* error,
132     std::vector<InstallWarning>* warnings) {
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->GetType())) &&
138         !handler->Validate(application, error, warnings))
139       return false;
140   }
141   return true;
142 }
143
144 // static
145 void ManifestHandlerRegistry::SetInstanceForTesting(
146     ManifestHandlerRegistry* registry, Manifest::PackageType package_type) {
147   if (package_type == Manifest::TYPE_WGT) {
148     widget_registry_ = registry;
149     return;
150   }
151
152   xpk_registry_ = registry;
153 }
154
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);
160   }
161
162   int order = 0;
163   while (true) {
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 "
177             << prerequisites[i];
178         // Prerequisite is in our map.
179         if (ContainsKey(order_map_, prereq_iter->second))
180           unsatisfied--;
181       }
182       if (unsatisfied == 0) {
183         order_map_[handler] = order;
184         order++;
185       } else {
186         // Put in the list for next time.
187         next_unsorted_handlers.insert(handler);
188       }
189     }
190     if (next_unsorted_handlers.size() == unsorted_handlers.size())
191       break;
192     unsorted_handlers.swap(next_unsorted_handlers);
193   }
194
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!";
199 }
200
201 }  // namespace application
202 }  // namespace xwalk