Replace GCM and polling with long polling
[fonbot.git] / src / ro / ieval / fonbot / HttpCallExecutableRunnable.java
1 package ro.ieval.fonbot;
2
3 import static ro.ieval.fonbot.R.string.*;
4 import static ro.ieval.fonbot.Utils.toNonNull;
5
6 import java.io.InputStream;
7 import java.io.OutputStream;
8 import java.net.URL;
9 import java.util.Collection;
10
11 import java.net.HttpURLConnection;
12 import org.eclipse.jdt.annotation.Nullable;
13
14 import android.content.Context;
15 import android.preference.PreferenceManager;
16 import android.util.Base64;
17 import android.util.Log;
18
19 import com.google.android.gcm.GCMRegistrar;
20
21 /*
22 * Copyright © 2013 Marius Gavrilescu
23 *
24 * This file is part of FonBot.
25 *
26 * FonBot is free software: you can redistribute it and/or modify
27 * it under the terms of the GNU General Public License as published by
28 * the Free Software Foundation, either version 3 of the License, or
29 * (at your option) any later version.
30 *
31 * FonBot is distributed in the hope that it will be useful,
32 * but WITHOUT ANY WARRANTY; without even the implied warranty of
33 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34 * GNU General Public License for more details.
35 *
36 * You should have received a copy of the GNU General Public License
37 * along with FonBot. If not, see <http://www.gnu.org/licenses/>.
38 */
39
40 /**
41 * ExecutableRunnable that makes a HTTP(S) call to the server and hands the response to a callback
42 *
43 * @author Marius Gavrilescu <marius@ieval.ro>
44 */
45 public final class HttpCallExecutableRunnable extends ExecutableRunnable{
46
47 /**
48 * Callback which is run after a HTTP call.
49 *
50 * @author Marius Gavrilescu
51 */
52 public interface ResultCallback{
53 /**
54 * Callback invoked if the HTTP call is successful.
55 *
56 * @param responseCode HTTP response code
57 * @param responseMessage HTTP response message
58 * @param inputStream HTTP content InputStream
59 */
60 void onResult(final int responseCode, final String responseMessage, final InputStream inputStream);
61 /**
62 * Callback invoked if the HTTP call is unsuccessful.
63 *
64 * @param error localized error message
65 */
66 void onError(final String error);
67 }
68
69 /**
70 * List of extra request headers.
71 */
72 private final Collection<Header> headers;
73 /**
74 * Context instance used by this class
75 */
76 private final Context context;
77 /**
78 * Data to send to the server
79 */
80 private final byte[] data;
81 /**
82 * Server URL path
83 */
84 private final String path;
85 /**
86 * Callback to run after the request returns
87 */
88 private final ResultCallback callback;
89 /** If true, the task should be retried if it fails */
90 private final boolean mustRetryTask;
91
92 /**
93 * Constructs a SendHttpMessageAsyncTask which sends a binary message.
94 *
95 * @param path URL path
96 * @param headers the extra headers
97 * @param context the context instance
98 * @param resultCallback {@link ResultCallback} instance
99 * @param mustRetryTask true if this task should be retried if it fails
100 * @param data the message to send
101 */
102 public HttpCallExecutableRunnable(final String path, final @Nullable Collection<Header> headers, final Context context, final @Nullable ResultCallback resultCallback, final boolean mustRetryTask, final byte[] data){//NOPMD array is supposed to be immutable.
103 this.path=path;
104 this.headers=headers;
105 this.context=context;
106 this.callback=resultCallback;
107 this.mustRetryTask=mustRetryTask;
108 this.data=data;
109 }
110
111 /**
112 * Constructs a SendHttpMessageAsyncTask which sends a text message.
113 *
114 * @param path URL path
115 * @param headers the extra headers
116 * @param context the context instance
117 * @param resultCallback {@link ResultCallback} instance
118 * @param mustRetryTask true if this task should be retried if it fails
119 * @param message message to send
120 */
121 public HttpCallExecutableRunnable(final String path, final @Nullable Collection<Header> headers, final Context context, final @Nullable ResultCallback resultCallback, final boolean mustRetryTask, final String... message){
122 this.path=path;
123 this.headers=headers;
124 this.context=context;
125 this.callback=resultCallback;
126 this.mustRetryTask=mustRetryTask;
127 if(message.length == 0)
128 this.data=null;//NOPMD final field
129 else
130 this.data=Utils.join(" ", message).getBytes();
131 }
132
133 @Override
134 public void run() {
135 try {
136 final URL url=Utils.getServerURL(toNonNull(context),toNonNull(path));
137 final HttpURLConnection conn=(HttpURLConnection) url.openConnection();
138 if(data!=null){
139 conn.setDoOutput(true);
140 conn.setFixedLengthStreamingMode(data.length);
141 }
142 conn.setRequestProperty("X-ID", GCMRegistrar.getRegistrationId(context));
143 final String user=PreferenceManager.getDefaultSharedPreferences(context).getString("username", null);
144 final String password=PreferenceManager.getDefaultSharedPreferences(context).getString("password", null);
145 if(user == null || password == null){
146 if(callback!=null)
147 callback.onError(toNonNull(context.getString(user_or_password_not_set)));
148 return;
149 }
150
151 conn.setRequestProperty("Authorization", "Basic "+Base64.encodeToString(
152 (user+':'+password).getBytes(), Base64.NO_WRAP));
153 if(headers != null)
154 for (final Header header : headers)
155 conn.setRequestProperty(header.name, header.value);
156 conn.connect();
157 if(data!=null){
158 final OutputStream stream=conn.getOutputStream();
159 stream.write(data);
160 stream.close();
161 }
162 Log.d(getClass().getName(),"HTTP Response: "+conn.getResponseCode()+" "+conn.getResponseMessage());
163 final String message=conn.getResponseMessage();
164 if(message==null && callback != null)
165 callback.onError(toNonNull(context.getString(no_response_returned_from_server)));
166 else if(message != null && callback != null)
167 callback.onResult(conn.getResponseCode(), message,
168 toNonNull(conn.getInputStream()));
169 conn.disconnect();
170 } catch (Exception e) {
171 e.printStackTrace();
172 if(callback != null)
173 callback.onError(toNonNull(context.getString(connection_error)));
174 if(mustRetryTask)
175 retry();
176 }
177 }
178 }
This page took 0.024461 seconds and 4 git commands to generate.