e6107dd3eee5a2239d544907e8e2860eb6fb8b2f
[platform/framework/web/crosswalk.git] / src / xwalk / application / common / manifest_handlers / widget_handler.cc
1 // Copyright (c) 2014 Intel Corporation. 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_handlers/widget_handler.h"
6
7 #include <map>
8 #include <utility>
9 #include <set>
10
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/strings/string_split.h"
14 #include "xwalk/application/common/application_manifest_constants.h"
15
16 namespace xwalk {
17
18 namespace keys = application_widget_keys;
19
20 namespace {
21 // Below key names are readable from Javascript widget interface.
22 const char kAuthor[] = "author";
23 const char kDecription[] = "description";
24 const char kName[] = "name";
25 const char kShortName[] = "shortName";
26 const char kVersion[] = "version";
27 const char kID[] = "id";
28 const char kAuthorEmail[] = "authorEmail";
29 const char kAuthorHref[] = "authorHref";
30 const char kHeight[] = "height";
31 const char kWidth[] = "width";
32 const char kPreferences[] = "preferences";
33
34 // Child keys inside 'preferences' key.
35 const char kPreferencesName[] = "name";
36 const char kPreferencesValue[] = "value";
37 const char kPreferencesReadonly[] = "readonly";
38
39 typedef std::map<std::string, std::string> KeyMap;
40 typedef std::map<std::string, std::string>::const_iterator KeyMapIterator;
41 typedef std::pair<std::string, std::string> KeyPair;
42
43 const KeyMap& GetWidgetKeyPairs() {
44   static KeyMap map;
45   if (map.empty()) {
46     map.insert(KeyPair(keys::kAuthorKey, kAuthor));
47     map.insert(KeyPair(keys::kDescriptionKey, kDecription));
48     map.insert(KeyPair(keys::kNameKey, kName));
49     map.insert(KeyPair(keys::kShortNameKey, kShortName));
50     map.insert(KeyPair(keys::kVersionKey, kVersion));
51     map.insert(KeyPair(keys::kIDKey, kID));
52     map.insert(KeyPair(keys::kAuthorEmailKey, kAuthorEmail));
53     map.insert(KeyPair(keys::kAuthorHrefKey, kAuthorHref));
54     map.insert(KeyPair(keys::kHeightKey, kHeight));
55     map.insert(KeyPair(keys::kWidthKey, kWidth));
56   }
57
58   return map;
59 }
60
61 bool ParsePreferenceItem(const base::DictionaryValue* in_value,
62                          base::DictionaryValue* out_value,
63                          std::set<std::string>* used) {
64   DCHECK(in_value && in_value->IsType(base::Value::TYPE_DICTIONARY));
65
66   std::string pref_name;
67   std::string pref_value;
68   std::string pref_readonly;
69   if (in_value->GetString(keys::kPreferencesNameKey, &pref_name)
70      && used->find(pref_name) == used->end()) {
71     out_value->SetString(kPreferencesName, pref_name);
72     used->insert(pref_name);
73   } else {
74     return false;
75   }
76
77   if (in_value->GetString(keys::kPreferencesValueKey, &pref_value))
78     out_value->SetString(kPreferencesValue, pref_value);
79
80   if (in_value->GetString(keys::kPreferencesReadonlyKey, &pref_readonly))
81     out_value->SetBoolean(kPreferencesReadonly, pref_readonly == "true");
82   return true;
83 }
84
85 }  // namespace
86
87 namespace application {
88
89 WidgetInfo::WidgetInfo()
90     : value_(new base::DictionaryValue) {}
91
92 WidgetInfo::~WidgetInfo() {}
93
94 void WidgetInfo::SetString(const std::string& key, const std::string& value) {
95   value_->SetString(key, value);
96 }
97
98 void WidgetInfo::Set(const std::string& key, base::Value* value) {
99   value_->Set(key, value);
100 }
101
102 void WidgetInfo::SetName(const std::string& name) {
103   value_->SetString(kName, name);
104 }
105
106 void WidgetInfo::SetShortName(const std::string& short_name) {
107   value_->SetString(kShortName, short_name);
108 }
109
110 void WidgetInfo::SetDescription(const std::string& description) {
111   value_->SetString(kDecription, description);
112 }
113
114 WidgetHandler::WidgetHandler() {}
115
116 WidgetHandler::~WidgetHandler() {}
117
118 bool WidgetHandler::Parse(scoped_refptr<ApplicationData> application,
119                           base::string16* error) {
120   scoped_ptr<WidgetInfo> widget_info(new WidgetInfo);
121   const Manifest* manifest = application->GetManifest();
122   DCHECK(manifest);
123
124   const KeyMap& map = GetWidgetKeyPairs();
125
126   for (KeyMapIterator iter = map.begin(); iter != map.end(); ++iter) {
127     std::string string;
128     bool result = manifest->GetString(iter->first, &string);
129     widget_info->SetString(iter->second, result ? string : "");
130   }
131
132   base::Value* pref_value = NULL;
133   manifest->Get(keys::kPreferencesKey, &pref_value);
134
135   std::set<std::string> preference_names_used;
136   if (pref_value && pref_value->IsType(base::Value::TYPE_DICTIONARY)) {
137     base::DictionaryValue* preferences = new base::DictionaryValue;
138     base::DictionaryValue* dict;
139     pref_value->GetAsDictionary(&dict);
140     if (ParsePreferenceItem(dict, preferences, &preference_names_used))
141       widget_info->Set(kPreferences, preferences);
142   } else if (pref_value && pref_value->IsType(base::Value::TYPE_LIST)) {
143     base::ListValue* preferences = new base::ListValue;
144     base::ListValue* list;
145     pref_value->GetAsList(&list);
146
147     for (base::ListValue::iterator it = list->begin();
148          it != list->end(); ++it) {
149       base::DictionaryValue* pref = new base::DictionaryValue;
150       base::DictionaryValue* dict;
151       (*it)->GetAsDictionary(&dict);
152       if (ParsePreferenceItem(dict, pref, &preference_names_used))
153         preferences->Append(pref);
154     }
155     widget_info->Set(kPreferences, preferences);
156   }
157
158   application->SetManifestData(keys::kWidgetKey, widget_info.release());
159   return true;
160 }
161
162 bool WidgetHandler::Validate(
163     scoped_refptr<const ApplicationData> application,
164     std::string* error) const {
165   const Manifest* manifest = application->GetManifest();
166   DCHECK(manifest);
167   std::string ns_value;
168   manifest->GetString(kW3CNamespaceKey, &ns_value);
169   if (base::strcasecmp(kW3CNamespacePrefix, ns_value.c_str()) != 0) {
170     *error = std::string("The widget namespace is invalid.");
171     return false;
172   }
173   return true;
174 }
175
176 bool WidgetHandler::AlwaysParseForType(Manifest::Type type) const {
177   return true;
178 }
179
180 std::vector<std::string> WidgetHandler::Keys() const {
181   return std::vector<std::string>(1, keys::kWidgetKey);
182 }
183
184 }  // namespace application
185 }  // namespace xwalk