The license change version 1.0 to version 1.1
[platform/framework/web/web-provider.git] / src / Core / BoxSchemeHandler.cpp
1 /*
2  * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Flora License, Version 1.1 (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://floralicense.org/license/
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    BoxSchemeHandler.cpp
18  * @author  Yunchan Cho (yunchan.cho@samsung.com)
19  */
20
21 #include <string.h>
22 #include "Box.h"
23 #include "Service/AppControl.h"
24 #include "Service/PeriodChanger.h"
25 #include "Service/ScrollHolder.h"
26 #include "Util/Log.h"
27 #include "BoxSchemeHandler.h"
28
29 static const std::string BOX_SCHEME("box://");
30 static const std::string BOX_SCHEME_RELOAD("box://reload");
31 static const std::string BOX_SCHEME_CHANGE_PERIOD("box://change-period");
32 static const std::string BOX_SCHEME_LAUNCH_BROWSER("box://launch-browser");
33 static const std::string BOX_SCHEME_SCROLL_START("box://scroll-start");
34 static const std::string BOX_SCHEME_SCROLL_STOP("box://scroll-stop");
35
36 static const std::string HTTP_SCHEME("http://");
37 static const std::string HTTPS_SCHEME("https://");
38
39 // static variable intialization
40 BoxSchemeHandler* BoxSchemeHandler::s_instance = NULL;
41
42 BoxSchemeHandler::BoxSchemeHandler()
43     : m_boxMap()
44 {
45     LogD("enter");
46 }
47
48 BoxSchemeHandler::~BoxSchemeHandler()
49 {
50     LogD("enter");
51 }
52
53 BoxSchemeHandler* BoxSchemeHandler::Instance()
54 {
55     LogD("enter");
56     if (!s_instance) {
57         s_instance = new BoxSchemeHandler();
58     }
59
60     return s_instance;
61 }
62
63 void BoxSchemeHandler::registerBox(std::string& instanceId, Box* box)
64 {
65     LogD("enter");
66
67     if (getBox(instanceId)) {
68         LogD("already registered");
69         return;
70     }
71
72     m_boxMap.insert(BoxMapPair(instanceId, box));
73 }
74
75 void BoxSchemeHandler::unregisterBox(std::string& instanceId)
76 {
77     LogD("enter");
78     m_boxMap.erase(instanceId);
79 }
80
81 bool BoxSchemeHandler::process(std::string& instanceId, std::string& uri)
82 {
83     LogD("enter");
84
85     if (!isBoxScheme(uri)) {
86         return false;
87     }
88
89     if (!uri.compare(BOX_SCHEME_RELOAD)) {
90        return handleReload(instanceId);
91     }
92
93     if (!uri.compare(
94                 0,
95                 BOX_SCHEME_CHANGE_PERIOD.size(),
96                 BOX_SCHEME_CHANGE_PERIOD)) 
97     {
98         std::string key("period");
99         std::string period = parse(uri, key);
100         if (period.empty()) {
101             return handleChangePeriod(instanceId);
102         }
103
104         return handleChangePeriod(instanceId, std::atof(period.c_str()));
105     }
106
107     if (!uri.compare(
108                 0,
109                 BOX_SCHEME_LAUNCH_BROWSER.size(),
110                 BOX_SCHEME_LAUNCH_BROWSER))
111     {
112         std::string key("url");
113         std::string url = parse(uri, key);
114         return handleLaunchBrowser(instanceId, url);
115     }
116
117     if (!uri.compare(BOX_SCHEME_SCROLL_START)) {
118        return handleScroll(instanceId, true);
119     }
120
121     if (!uri.compare(BOX_SCHEME_SCROLL_STOP)) {
122        return handleScroll(instanceId, false);
123     }
124
125     LogD("unknown box scheme protocol");
126     return false;
127 }
128
129 bool BoxSchemeHandler::isBoxScheme(std::string& uri)
130 {
131     LogD("enter");
132     if(!uri.compare(0, BOX_SCHEME.size(), BOX_SCHEME)) {
133         return true;
134     }
135
136     return false;
137 }
138
139 Box* BoxSchemeHandler::getBox(std::string& instanceId)
140 {
141     LogD("enter");
142
143     auto it = m_boxMap.find(instanceId);
144     if (it != m_boxMap.end()) {
145         LogD("registered: %s (%p)", it->first.c_str(), it->second);
146         return it->second;
147     }
148
149     return NULL;
150 }
151
152 bool BoxSchemeHandler::handleScroll(std::string& instanceId, bool start)
153 {
154     using namespace Service::ScrollHolder;
155
156     LogD("enter");
157         Box* box = getBox(instanceId);
158     if (!box) {
159         LogD("unregistered instance");
160         return false;
161     }
162
163     holdHorizontalScroll(box->m_boxInfo->boxId, instanceId, start);
164     return true;
165 }
166
167 bool BoxSchemeHandler::handleReload(std::string& instanceId)
168 {
169     LogD("enter");
170     Box* box = getBox(instanceId);
171     if (!box) {
172         LogD("unregistered instance");
173         return false;
174     }
175
176     box->update();
177     return true;
178 }
179
180 bool BoxSchemeHandler::handleChangePeriod(std::string& instanceId, float requestedPeriod)
181 {
182     LogD("enter");
183
184     Box* box = getBox(instanceId);
185     if (!box) {
186         LogD("no box for update period");
187         return false;
188     }
189
190     m_periodChanger =
191         Service::PeriodChanger::create(
192             box->m_boxInfo->boxId, instanceId,
193             box->m_boxInfo->period, requestedPeriod);
194
195     return m_periodChanger->change();
196 }
197
198 bool BoxSchemeHandler::handleLaunchBrowser(std::string& instanceId, std::string& url)
199 {
200     LogD("enter");
201     if(!url.compare(0, HTTP_SCHEME.size(), HTTP_SCHEME) ||
202        !url.compare(0, HTTPS_SCHEME.size(), HTTPS_SCHEME))
203     {
204         return Service::AppControl::launchBrowser(url);
205     }
206
207     return false;
208 }
209
210 std::string BoxSchemeHandler::parse(std::string& uri, std::string& key)
211 {
212     LogD("enter");
213
214     // TODO url parameter SHOULD be parsed using std::regex, not manually
215     std::string value("");
216
217     unsigned found = uri.find_first_of("?");
218     if (found == std::string::npos) {
219         LogD("no query");
220         return value;
221     }
222
223     std::string query = std::string(uri, found + 1);
224     found = 0;
225     do {
226         LogD("enter\n");
227         unsigned seperator = query.find_first_of("=", found + 1);
228         if (seperator == std::string::npos) {
229             LogD("no '=' character\n");
230             break;
231         }
232
233         unsigned next = query.find_first_of("@", found + 1);
234         if (!query.compare(found, key.size(), key)) {
235             LogD("key matched!\n");
236             value = std::string(query, seperator + 1, next - seperator - 1);
237             break;
238         }
239
240         found = next + 1;
241     } while (found && found != std::string::npos);
242
243     LogD("URL query parsing result: key -> %s, value -> %s", key.c_str(), value.c_str());
244     return value;
245 }