Improve JSON parsing
[fonbot.git] / src / ro / ieval / fonbot / PollServerAsyncTask.java
CommitLineData
8dfb76c9
MG
1package ro.ieval.fonbot;
2
3import static ro.ieval.fonbot.Utils.toNonNull;
4
5import java.io.IOException;
6import java.net.HttpURLConnection;
7import java.net.MalformedURLException;
8import java.net.URL;
9import java.util.ArrayList;
10import java.util.List;
11
12import org.eclipse.jdt.annotation.Nullable;
13import org.json.JSONArray;
14import org.json.JSONException;
15import org.json.JSONObject;
16
17import ro.ieval.fonbot.Address.Protocol;
a97d31fb 18import android.content.Context;
8dfb76c9 19import android.os.AsyncTask;
d13f1533
MG
20import android.preference.PreferenceManager;
21import android.util.Base64;
8dfb76c9
MG
22import android.util.Log;
23
8bfdcf7a
MG
24import com.google.android.gcm.GCMRegistrar;
25
8dfb76c9
MG
26/*
27 * Copyright © 2013 Marius Gavrilescu
28 *
29 * This file is part of FonBot.
30 *
31 * FonBot is free software: you can redistribute it and/or modify
32 * it under the terms of the GNU General Public License as published by
33 * the Free Software Foundation, either version 3 of the License, or
34 * (at your option) any later version.
35 *
36 * FonBot is distributed in the hope that it will be useful,
37 * but WITHOUT ANY WARRANTY; without even the implied warranty of
38 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39 * GNU General Public License for more details.
40 *
41 * You should have received a copy of the GNU General Public License
42 * along with FonBot. If not, see <http://www.gnu.org/licenses/>.
43 */
44
45/**
46 * AsyncTask that polls the server for pending commands and executes any commands found.
47 *
48 * @author Marius Gavrilescu <marius@ieval.ro>
49 */
50public final class PollServerAsyncTask extends AsyncTask<Void, Void, List<PollServerAsyncTask.Command>> {
51 /**
52 * POJO that represents a command in a basic form: a command name, a list of arguments and a reply address, all of them being strings
53 *
54 * @author Marius Gavrilescu <marius@ieval.ro>
55 */
56 final class Command{
57 /**
58 * The command name
59 */
60 final String command;//NOPMD no confusion here
61 /**
62 * The list of command arguments
63 */
64 final String[] args;
65 /**
66 * The reply address, excluding the protocol
67 */
68 final String replyto;
69
70 /**
71 * Construct a Command from its three parts
72 *
73 * @param command the command name
74 * @param args the command arguments
75 * @param replyto the reply address
76 */
77 Command(final String command, final String[] args, final String replyto) {//NOPMD array is immutable
78 this.command=command;
79 this.args=args;
80 this.replyto=replyto;
81 }
82 }
83
a97d31fb
MG
84 /** Context instance */
85 private final Context context;
86
87 /**
88 * Constructs a PollServerAsyncTask.
89 *
90 * @param context Context instance
91 */
92 public PollServerAsyncTask(final Context context) {
93 this.context=context;
94 }
95
8dfb76c9
MG
96 @Override
97 protected List<Command> doInBackground(final @Nullable Void... params) {
98 Log.d(getClass().getName(), "Polling server");
99 final List<Command> commands=new ArrayList<Command>(10);
100 try {
a97d31fb 101 final URL url=Utils.getServerURL(toNonNull(context),"/get");
8dfb76c9 102 final HttpURLConnection conn=(HttpURLConnection) url.openConnection();
8bfdcf7a 103 conn.setRequestProperty("X-ID", GCMRegistrar.getRegistrationId(context));
d13f1533
MG
104 final String user=PreferenceManager.getDefaultSharedPreferences(context).getString("username", null);
105 final String password=PreferenceManager.getDefaultSharedPreferences(context).getString("password", null);
106 if(user == null || password == null)
107 return commands;
108
109 conn.setRequestProperty("Authorization", "Basic "+Base64.encodeToString(
110 (user+':'+password).getBytes(), Base64.NO_WRAP));
8dfb76c9 111 conn.connect();
8dfb76c9
MG
112 Log.d(getClass().getName(), "Server poll got response code "+conn.getResponseCode()+" and message "+conn.getResponseMessage());
113 if(conn.getResponseCode()!=200)
114 return commands;
9ead79ec
MG
115
116 final JSONArray array;
117 {
118 final byte[] buf=new byte[4096*1024];
119 conn.getInputStream().read(buf);
120 array=new JSONArray(new String(buf));
121 }
122
8dfb76c9
MG
123 for(int i=0;i<array.length();i++){
124 final JSONObject object=array.getJSONObject(i);
125
9ead79ec
MG
126 final JSONArray jsonargs=object.getJSONArray("args");
127 final String[] args=new String[jsonargs.length()];
128 for(int j=0;j<args.length;j++)
129 args[j]=jsonargs.getString(j);
8dfb76c9
MG
130
131 commands.add(new Command(//NOPMD command changes for each JSON object
132 toNonNull(object.getString("command")),
9ead79ec 133 args,
8dfb76c9 134 toNonNull(object.getString("replyto"))));
8dfb76c9
MG
135 }
136 } catch (MalformedURLException e) {
137 e.printStackTrace();
138 } catch (IOException e) {
139 e.printStackTrace();
140 } catch (JSONException e) {
141 e.printStackTrace();
142 }
143 if(commands==null)
144 throw new AssertionError("commands is null in PollServerAsyncTask#doInBackground");//silence Eclipse bug
145 return commands;
146 }
147
148 @Override
149 protected void onPostExecute(final @Nullable List<Command> commands) {
150 if(commands==null)
151 return;
152 for (Command command : commands) {
153 Log.d(getClass().getName(), "Poll got command "+command.command+" with "+((command.args.length==0)?"no args":"args "+Utils.join(
154 " ",toNonNull(command.args))));
155 Utils.processCommand(
8bfdcf7a 156 toNonNull(context),
8dfb76c9
MG
157 toNonNull(command.command),
158 toNonNull(command.args),
159 new Address(toNonNull(Protocol.HTTP), command.replyto));//NOPMD address depends on command
160 }
161 }
162}
This page took 0.018939 seconds and 4 git commands to generate.