7f9a6305f95d48f5804a7443ea5ec024533153ac
[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 #include "xwalk/application/common/manifest_handlers/tizen_metadata_handler.h"
16 #include "xwalk/application/common/manifest_handlers/tizen_setting_handler.h"
17 #endif
18 #include "xwalk/application/common/manifest_handlers/permissions_handler.h"
19 #include "xwalk/application/common/manifest_handlers/warp_handler.h"
20 #include "xwalk/application/common/manifest_handlers/widget_handler.h"
21
22 namespace xwalk {
23 namespace application {
24
25 ManifestHandler::~ManifestHandler() {
26 }
27
28 bool ManifestHandler::Validate(scoped_refptr<const ApplicationData> application,
29                                std::string* error,
30                                std::vector<InstallWarning>* warnings) const {
31   return true;
32 }
33
34 bool ManifestHandler::AlwaysParseForType(Manifest::Type type) const {
35   return false;
36 }
37
38 bool ManifestHandler::AlwaysValidateForType(Manifest::Type type) const {
39   return false;
40 }
41
42 std::vector<std::string> ManifestHandler::PrerequisiteKeys() const {
43   return std::vector<std::string>();
44 }
45
46 ManifestHandlerRegistry* ManifestHandlerRegistry::xpk_registry_ = NULL;
47 ManifestHandlerRegistry* ManifestHandlerRegistry::widget_registry_ = NULL;
48
49 ManifestHandlerRegistry::ManifestHandlerRegistry(
50     const std::vector<ManifestHandler*>& handlers) {
51   for (std::vector<ManifestHandler*>::const_iterator it = handlers.begin();
52        it != handlers.end(); ++it) {
53     Register(*it);
54   }
55
56   ReorderHandlersGivenDependencies();
57 }
58
59 ManifestHandlerRegistry::~ManifestHandlerRegistry() {
60 }
61
62 ManifestHandlerRegistry*
63 ManifestHandlerRegistry::GetInstance(Manifest::PackageType package_type) {
64   if (package_type == Manifest::TYPE_WGT)
65     return GetInstanceForWGT();
66   return GetInstanceForXPK();
67 }
68
69 ManifestHandlerRegistry*
70 ManifestHandlerRegistry::GetInstanceForWGT() {
71   if (widget_registry_)
72     return widget_registry_;
73
74   std::vector<ManifestHandler*> handlers;
75   // We can put WGT specific manifest handlers here.
76   handlers.push_back(new WidgetHandler);
77   handlers.push_back(new WARPHandler);
78 #if defined(OS_TIZEN)
79   handlers.push_back(new CSPHandler(Manifest::TYPE_WGT));
80   handlers.push_back(new NavigationHandler);
81   handlers.push_back(new TizenApplicationHandler);
82   handlers.push_back(new TizenSettingHandler);
83   handlers.push_back(new TizenMetaDataHandler);
84 #endif
85   widget_registry_ = new ManifestHandlerRegistry(handlers);
86   return widget_registry_;
87 }
88
89 ManifestHandlerRegistry*
90 ManifestHandlerRegistry::GetInstanceForXPK() {
91   if (xpk_registry_)
92     return xpk_registry_;
93
94   std::vector<ManifestHandler*> handlers;
95   // FIXME: Add manifest handlers here like this:
96   // handlers.push_back(new xxxHandler);
97   handlers.push_back(new CSPHandler(Manifest::TYPE_XPK));
98   handlers.push_back(new MainDocumentHandler);
99   handlers.push_back(new PermissionsHandler);
100   xpk_registry_ = new ManifestHandlerRegistry(handlers);
101   return xpk_registry_;
102 }
103
104 void ManifestHandlerRegistry::Register(ManifestHandler* handler) {
105   const std::vector<std::string>& keys = handler->Keys();
106   for (size_t i = 0; i < keys.size(); ++i) {
107     handlers_[keys[i]] = handler;
108   }
109 }
110
111 bool ManifestHandlerRegistry::ParseAppManifest(
112     scoped_refptr<ApplicationData> application, base::string16* error) {
113   std::map<int, ManifestHandler*> handlers_by_order;
114   for (ManifestHandlerMap::iterator iter = handlers_.begin();
115        iter != handlers_.end(); ++iter) {
116     ManifestHandler* handler = iter->second;
117     if (application->GetManifest()->HasPath(iter->first) ||
118         handler->AlwaysParseForType(application->GetType())) {
119       handlers_by_order[order_map_[handler]] = handler;
120     }
121   }
122   for (std::map<int, ManifestHandler*>::iterator iter =
123            handlers_by_order.begin();
124        iter != handlers_by_order.end(); ++iter) {
125     if (!(iter->second)->Parse(application, error))
126       return false;
127   }
128   return true;
129 }
130
131 bool ManifestHandlerRegistry::ValidateAppManifest(
132     scoped_refptr<const ApplicationData> application,
133     std::string* error,
134     std::vector<InstallWarning>* warnings) {
135   for (ManifestHandlerMap::iterator iter = handlers_.begin();
136        iter != handlers_.end(); ++iter) {
137     ManifestHandler* handler = iter->second;
138     if ((application->GetManifest()->HasPath(iter->first) ||
139          handler->AlwaysValidateForType(application->GetType())) &&
140         !handler->Validate(application, error, warnings))
141       return false;
142   }
143   return true;
144 }
145
146 // static
147 void ManifestHandlerRegistry::SetInstanceForTesting(
148     ManifestHandlerRegistry* registry, Manifest::PackageType package_type) {
149   if (package_type == Manifest::TYPE_WGT) {
150     widget_registry_ = registry;
151     return;
152   }
153
154   xpk_registry_ = registry;
155 }
156
157 void ManifestHandlerRegistry::ReorderHandlersGivenDependencies() {
158   std::set<ManifestHandler*> unsorted_handlers;
159   for (ManifestHandlerMap::const_iterator iter = handlers_.begin();
160        iter != handlers_.end(); ++iter) {
161     unsorted_handlers.insert(iter->second);
162   }
163
164   int order = 0;
165   while (true) {
166     std::set<ManifestHandler*> next_unsorted_handlers;
167     for (std::set<ManifestHandler*>::const_iterator iter =
168              unsorted_handlers.begin();
169          iter != unsorted_handlers.end(); ++iter) {
170       ManifestHandler* handler = *iter;
171       const std::vector<std::string>& prerequisites =
172           handler->PrerequisiteKeys();
173       int unsatisfied = prerequisites.size();
174       for (size_t i = 0; i < prerequisites.size(); ++i) {
175         ManifestHandlerMap::const_iterator prereq_iter =
176             handlers_.find(prerequisites[i]);
177         CHECK(prereq_iter != handlers_.end())
178             << "Application manifest handler depends on unrecognized key "
179             << prerequisites[i];
180         // Prerequisite is in our map.
181         if (ContainsKey(order_map_, prereq_iter->second))
182           unsatisfied--;
183       }
184       if (unsatisfied == 0) {
185         order_map_[handler] = order;
186         order++;
187       } else {
188         // Put in the list for next time.
189         next_unsorted_handlers.insert(handler);
190       }
191     }
192     if (next_unsorted_handlers.size() == unsorted_handlers.size())
193       break;
194     unsorted_handlers.swap(next_unsorted_handlers);
195   }
196
197   // If there are any leftover unsorted handlers, they must have had
198   // circular dependencies.
199   CHECK(unsorted_handlers.empty()) << "Application manifest handlers have "
200                                    << "circular dependencies!";
201 }
202
203 }  // namespace application
204 }  // namespace xwalk