5cfc1408d7960f6da9bf661f90dde06776481c98
[situare] / src / network / networkaccessmanager.cpp
1 /*
2    Situare - A location system for Facebook
3    Copyright (C) 2010  Ixonos Plc. Authors:
4
5        Jussi Laitinen - jussi.laitinen@ixonos.com
6
7    Situare is free software; you can redistribute it and/or
8    modify it under the terms of the GNU General Public License
9    version 2 as published by the Free Software Foundation.
10
11    Situare is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with Situare; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
19    USA.
20 */
21
22 #include <QDebug>
23 #include <QNetworkAccessManager>
24 #include <QNetworkRequest>
25 #include <QTimer>
26
27 #include "networkhandler.h"
28 #include "networkreply.h"
29
30 #include "networkaccessmanager.h"
31
32 NetworkAccessManager::NetworkAccessManager(QObject *parent)
33     : QObject(parent),
34       m_connected(false),
35       m_networkHandler(0),
36       m_networkAccessManagerPrivate(0)
37 {
38     qDebug() << __PRETTY_FUNCTION__;
39
40     m_networkHandler = NetworkHandler::instance();
41     m_networkAccessManagerPrivate = new QNetworkAccessManager(this);
42
43     connect(m_networkHandler, SIGNAL(connected()),
44             this, SLOT(connected()));
45     connect(m_networkHandler, SIGNAL(disconnected()),
46             this, SLOT(disconnected()));
47
48     connect(m_networkAccessManagerPrivate, SIGNAL(finished(QNetworkReply*)),
49             this, SLOT(downloadFinished(QNetworkReply*)));
50 }
51
52 QAbstractNetworkCache *NetworkAccessManager::cache() const
53 {
54     qDebug() << __PRETTY_FUNCTION__;
55
56     return m_networkAccessManagerPrivate->cache();
57 }
58
59 void NetworkAccessManager::connected()
60 {
61     qDebug() << __PRETTY_FUNCTION__;
62
63     m_connected = true;
64
65     //Loop through all requests and calls get method.
66     foreach (const QNetworkRequest &request, m_requestQueue) {
67         QNetworkReply *reply = m_networkAccessManagerPrivate->get(request);
68         m_temporaryReplyQueue.insert(request.url().toString(), reply);
69     }
70
71     m_requestQueue.clear();
72 }
73
74 void NetworkAccessManager::disconnected()
75 {
76     qDebug() << __PRETTY_FUNCTION__;
77
78     m_connected = false;
79 }
80
81 void NetworkAccessManager::downloadFinished(QNetworkReply *reply)
82 {
83     qDebug() << __PRETTY_FUNCTION__;
84
85     QString key = m_temporaryReplyQueue.key(reply, "");
86
87     //Replace offline reply object's content with server reply's content
88     if (!key.isEmpty()) {
89         QNetworkReply *offlineReply = m_offlineReplyQueue.value(key, 0);
90
91         if (offlineReply) {
92             memmove(offlineReply, reply, sizeof(QNetworkReply));
93             m_offlineReplyQueue.remove(key);
94             m_temporaryReplyQueue.remove(key);
95             emit finished(offlineReply);
96         }
97     }
98     //Forward online request's reply
99     else {
100         emit finished(reply);
101     }
102 }
103
104 QNetworkReply *NetworkAccessManager::get(const QNetworkRequest &request, bool onlineRequestsOnly)
105 {
106     qDebug() << __PRETTY_FUNCTION__;
107
108     //Disconnected from network, queue request and return empty reply.
109     if (!m_networkHandler->isConnected()) {
110         m_requestQueue.append(request);
111         m_networkHandler->connect();
112         QNetworkReply *reply = new NetworkReply(request, this);
113
114         if (onlineRequestsOnly) {
115             ((NetworkReply*)reply)->setErrorCode(QNetworkReply::UnknownNetworkError);
116             emit finished(reply);
117         }
118         else {
119             m_offlineReplyQueue.insert(request.url().toString(), reply);
120         }
121
122         return reply;
123     }
124     //Connected, use normal get method.
125     else {
126         return m_networkAccessManagerPrivate->get(request);
127     }
128 }
129
130 QNetworkReply *NetworkAccessManager::post(const QNetworkRequest &request, QByteArray &data,
131                                           bool onlineRequestsOnly)
132 {
133     qDebug() << __PRETTY_FUNCTION__;
134
135     //Disconnected from network, queue request and return empty reply.
136     if (!m_networkHandler->isConnected()) {
137         m_requestQueue.append(request);
138         m_networkHandler->connect();
139         QNetworkReply *reply = new NetworkReply(request, this);
140
141         if (onlineRequestsOnly) {
142             ((NetworkReply*)reply)->setErrorCode(QNetworkReply::UnknownNetworkError);
143             emit finished(reply);
144         }
145         else {
146             m_offlineReplyQueue.insert(request.url().toString(), reply);
147         }
148
149         return reply;
150     }
151     //Connected, use normal post method.
152     else {
153         return m_networkAccessManagerPrivate->post(request, data);
154     }
155 }
156
157 bool NetworkAccessManager::isConnected()
158 {
159     qDebug() << __PRETTY_FUNCTION__;
160
161     return m_connected;
162 }
163
164 void NetworkAccessManager::setCache(QAbstractNetworkCache *cache)
165 {
166     qDebug() << __PRETTY_FUNCTION__;
167
168     m_networkAccessManagerPrivate->setCache(cache);
169 }