Source code formating unification
[platform/framework/web/wrt.git] / src / view / common / view_logic_uri_support.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /**
17  * @file    view_logic_uri_support.cpp
18  * @author  Pawel Sikorski (p.sikorski@samsung.com)
19  * @brief   Implementation file of UriSupport API used by ViewLogic
20  */
21
22 #include "view_logic_uri_support.h"
23 #include <string>
24 #include <vector>
25 #include <list>
26 #include <dpl/string.h>
27 #include <dpl/log/log.h>
28 #include <dpl/localization/w3c_file_localization.h>
29 #include <widget_model.h>
30 #include <bundle.h>
31 #include <appsvc.h>
32 #include <application_data.h>
33 #include <wrt-commons/custom-handler-dao-ro/CustomHandlerDatabase.h>
34 #include <wrt-commons/custom-handler-dao-ro/custom_handler_dao_read_only.h>
35 #include <stdio.h>
36
37 namespace ViewModule {
38 namespace UriSupport {
39 namespace {
40 enum ServiceDataType
41 {
42     SERVICE_DATA_TYPE_OPERATION,
43     SERVICE_DATA_TYPE_URI,
44     SERVICE_DATA_TYPE_MIME,
45     SERVICE_DATA_TYPE_MIME_ELEMENT
46 };
47
48 char const * const SCHEME_TYPE_FILE = "file";
49 char const * const SCHEME_TYPE_WIDGET = "widget";
50 char const * const SERVICE_DATA_WILD_CHAR = "*";
51 char const * const SERVICE_DATA_MIME_TOKEN = "/";
52 const unsigned int SIZE_OF_MIME_ELEMENT = 2;
53
54 std::list<std::string> parsingMimeData(std::string origin, std::string token)
55 {
56     std::list<std::string> parsedData;
57     size_t current = 0;
58     size_t next = 0;
59     do {
60         next = origin.find_first_of(token, current);
61         parsedData.push_back(origin.substr(current, next - current));
62         current = next + 1;
63     } while (next != std::string::npos && current < origin.length());
64     return parsedData;
65 }
66
67 /**
68  * Parses scheme from appsvc. From mailto:test@wacapps.net
69  * it will return list:
70  * 0: mailto
71  * 1: test@wacapps.net
72  */
73 std::vector<std::string> parseScheme(const std::string &scheme)
74 {
75     std::vector<std::string> schemeParts;
76     std::string::size_type pos = scheme.find(":");
77     if (pos != std::string::npos) {
78         schemeParts.push_back(scheme.substr(0, pos));
79         schemeParts.push_back(
80             scheme.substr(pos + 1, scheme.length() - pos - 1));
81     }
82     return schemeParts;
83 }
84
85 bool compareServiceData(ServiceDataType type,
86                         std::string origin,
87                         std::string other)
88 {
89     if (SERVICE_DATA_TYPE_OPERATION == type) {
90         return origin == other;
91     } else if (SERVICE_DATA_TYPE_URI == type
92                || SERVICE_DATA_TYPE_MIME_ELEMENT == type)
93     {
94         if (SERVICE_DATA_WILD_CHAR == origin) {
95             return true;
96         } else {
97             return origin == other;
98         }
99     } else if (SERVICE_DATA_TYPE_MIME == type) {
100         if (other == "") {
101             return origin == other;
102         }
103
104         std::list<std::string> vectorOrigin =
105             parsingMimeData(origin, SERVICE_DATA_MIME_TOKEN);
106         if (SIZE_OF_MIME_ELEMENT != vectorOrigin.size()) {
107             return false;
108         }
109         std::list<std::string> vectorOther =
110             parsingMimeData(other, SERVICE_DATA_MIME_TOKEN);
111         if (SIZE_OF_MIME_ELEMENT != vectorOther.size()) {
112             return false;
113         }
114
115         FOREACH(it, vectorOrigin) {
116             if (!compareServiceData(SERVICE_DATA_TYPE_MIME_ELEMENT,
117                                     *it,
118                                     vectorOther.front()))
119             {
120                 return false;
121             }
122             vectorOther.pop_front();
123         }
124         return true;
125     } else {
126         LogError("Wrong data type");
127         return false;
128     }
129 }
130 }
131
132 std::string prepareUrl(const std::string &url, const std::string &insert)
133 {
134     std::string urlFixed = url;
135     if (urlFixed.find("file://") == 0) {
136         urlFixed.erase(0, 6);
137     }
138     //replace %s in url with given from appservice
139     int size = snprintf(NULL, 0, urlFixed.c_str(), insert.c_str()) + 1;
140     char buffer[size];
141     snprintf(buffer, size, urlFixed.c_str(), insert.c_str());
142     return std::string(buffer);
143 }
144
145 std::string getCustomHandlerProtocolUri(
146     WidgetModel *widgetModel,
147     const std::string &schemeType,
148     const std::string &schemeValue)
149 {
150     CustomHandlerDB::Interface::attachDatabaseRO();
151     CustomHandlerDB::CustomHandlerDAOReadOnly handlersDao(widgetModel->TizenId);
152     CustomHandlerDB::CustomHandlerPtr handler =
153         handlersDao.getActivProtocolHandler(
154             DPL::FromASCIIString(schemeType));
155     CustomHandlerDB::Interface::detachDatabase();
156     if (handler) {
157         LogDebug("Found handler, url: " << handler->url);
158         return prepareUrl(DPL::ToUTF8String(handler->base_url) +
159                           DPL::ToUTF8String(handler->url), schemeValue);
160     }
161     return "";
162 }
163
164 std::string getCustomHandlerContentUri(
165     WidgetModel *widgetModel,
166     const std::string &mime,
167     const std::string &mimeValue)
168 {
169     CustomHandlerDB::Interface::attachDatabaseRO();
170     CustomHandlerDB::CustomHandlerDAOReadOnly handlersDao(widgetModel->TizenId);
171     CustomHandlerDB::CustomHandlerPtr handler =
172         handlersDao.getActivContentHandler(
173             DPL::FromASCIIString(mime));
174     CustomHandlerDB::Interface::detachDatabase();
175     if (handler) {
176         LogDebug("Found handler, url: " << handler->url);
177         return prepareUrl(DPL::ToUTF8String(handler->base_url) +
178                           DPL::ToUTF8String(handler->url), mimeValue);
179     }
180     return "";
181 }
182
183 std::string getAppServiceUri(bundle *bundle, WidgetModel *widgetModel)
184 {
185     if (!bundle) {
186         LogError("Bundle is empty");
187         return std::string("");
188     }
189
190     const char* value = NULL;
191     value = appsvc_get_operation(bundle);
192     std::string operation = value ? value : "";
193     value = appsvc_get_uri(bundle);
194     std::string scheme = value ? value : "";
195     value = appsvc_get_mime(bundle);
196     std::string mime = value ? value : "";
197
198     LogDebug("operation : " << operation);
199     LogDebug("schemeType : " << scheme);
200     LogDebug("mimetype : " << mime);
201
202     WidgetApplicationServiceList appServiceList =
203         widgetModel->AppServiceList.Get();
204     FOREACH(appServiceIt, appServiceList) {
205         if (compareServiceData(SERVICE_DATA_TYPE_OPERATION,
206                                DPL::ToUTF8String(appServiceIt->operation),
207                                operation) &&
208             compareServiceData(SERVICE_DATA_TYPE_URI,
209                                DPL::ToUTF8String(appServiceIt->scheme),
210                                scheme) &&
211             compareServiceData(SERVICE_DATA_TYPE_MIME,
212                                DPL::ToUTF8String(appServiceIt->mime),
213                                mime))
214         {
215             return DPL::ToUTF8String(appServiceIt->src);
216         }
217     }
218     std::vector<std::string> schemeParts = parseScheme(scheme);
219     if (schemeParts.size() > 1) {
220         LogDebug("Scheme parts: " << schemeParts[0] << ", " << schemeParts[1]);
221         return getCustomHandlerProtocolUri(
222                    widgetModel, schemeParts[0], schemeParts[1]);
223     }
224     if (mime != "") {
225         value = appsvc_get_data(bundle, APPSVC_DATA_SELECTED);
226         if (value != NULL) {
227             LogDebug("Use mime type for: " << value);
228             return getCustomHandlerContentUri(
229                        widgetModel, mime, std::string(value));
230         } else {
231             LogError("Selected file for mime is null, nothind to do");
232         }
233     }
234     LogDebug("no matching result");
235     return std::string("");
236 }
237
238 std::string getUri(WidgetModel *widgetModel, const std::string &defaultUri)
239 {
240     DPL::String uri;
241     std::string startUri;
242     LogDebug("default uri: " << defaultUri);
243     bundle *originBundle = ApplicationDataSingleton::Instance().getBundle();
244     // search application service
245     startUri = getAppServiceUri(originBundle, widgetModel).c_str();
246     LogInfo("application service start uri is " << startUri);
247     if (startUri == "") {
248         LogInfo("application service doesn't have matched data");
249         startUri = defaultUri;
250     } else {
251         // create encoded bundle data only for uri for application service
252         ApplicationDataSingleton::Instance().setEncodedBundle(originBundle);
253     }
254
255     // insert prefix path
256     std::string preFix = DPL::ToUTF8String(widgetModel->PrefixURL.Get());
257
258     if (strstr(startUri.c_str(), "http") == startUri.c_str() ||
259         strstr(startUri.c_str(), preFix.c_str()) == startUri.c_str())
260     {
261         uri = DPL::FromUTF8String(startUri);
262     } else {
263         uri = widgetModel->PrefixURL.Get() +
264             DPL::FromUTF8String(startUri);
265     }
266     return DPL::ToUTF8String(uri).c_str();
267 }
268
269 DPL::OptionalString localizeURI(const DPL::String& inputURI,
270                                 const WidgetModel* model)
271 {
272     auto uri = DPL::ToUTF8String(inputURI);
273     LogDebug("localizing url: " << uri);
274
275     auto urlcstr = uri.c_str();
276
277     const char *end = strstr(urlcstr, ":");
278     if (!end) {
279         LogDebug("no schema in link, return null");
280         // lack of schema
281         return DPL::Optional<DPL::String>::Null;
282     }
283
284     std::string scheme(urlcstr, end);
285     if (scheme != SCHEME_TYPE_WIDGET && scheme != SCHEME_TYPE_FILE) {
286         LogDebug("scheme doesn't need to localize");
287         return DPL::OptionalString(inputURI);
288     }
289
290     DPL::Optional<DPL::String> found =
291         W3CFileLocalization::getFilePathInWidgetPackageFromUrl(
292             model->TizenId,
293             DPL::FromUTF8String(uri));
294
295     if (found.IsNull()) {
296         // In this case, path doesn't need to localize. return input uri
297         LogDebug("Path not found within current locale in current widget");
298         return DPL::OptionalString(inputURI);
299     } else {
300         DPL::String uri(L"file://" + *found);
301         LogDebug("Will load resource: " << uri);
302         LogDebug("finished");
303         return DPL::OptionalString(uri);
304     }
305 }
306 } // namespace UriSupportImplementation
307 } // namespace ViewModule