e7f875e96f1aa432389255ccced1aefe17733eee
[public/netxms.git] / android / src / console / src / org / netxms / ui / android / main / activities / ConnectionPointBrowser.java
1 package org.netxms.ui.android.main.activities;
2
3 import java.io.IOException;
4 import java.util.ArrayList;
5 import java.util.List;
6
7 import org.json.JSONArray;
8 import org.json.JSONException;
9 import org.netxms.client.MacAddress;
10 import org.netxms.client.MacAddressFormatException;
11 import org.netxms.client.NXCException;
12 import org.netxms.client.NXCSession;
13 import org.netxms.client.objects.Interface;
14 import org.netxms.client.objects.Node;
15 import org.netxms.client.topology.ConnectionPoint;
16 import org.netxms.ui.android.R;
17 import org.netxms.ui.android.main.adapters.ConnectionPointListAdapter;
18 import org.netxms.ui.android.tools.BarcodeScannerIntegrator;
19 import org.netxms.ui.android.tools.BarcodeScannerIntentResult;
20
21 import android.app.AlertDialog;
22 import android.app.ProgressDialog;
23 import android.content.ComponentName;
24 import android.content.Context;
25 import android.content.DialogInterface;
26 import android.content.Intent;
27 import android.content.SharedPreferences;
28 import android.content.res.Resources;
29 import android.os.AsyncTask;
30 import android.os.Bundle;
31 import android.os.IBinder;
32 import android.preference.PreferenceManager;
33 import android.util.Log;
34 import android.view.ContextMenu;
35 import android.view.ContextMenu.ContextMenuInfo;
36 import android.view.KeyEvent;
37 import android.view.MenuItem;
38 import android.view.View;
39 import android.view.View.OnClickListener;
40 import android.view.View.OnKeyListener;
41 import android.widget.AdapterView;
42 import android.widget.AdapterView.AdapterContextMenuInfo;
43 import android.widget.Button;
44 import android.widget.EditText;
45 import android.widget.ListView;
46 import android.widget.TextView;
47
48 /**
49 * MAC address search result browser
50 *
51 * @author Marco Incalcaterra (marco.incalcaterra@thinksoft.it)
52 *
53 */
54
55 public class ConnectionPointBrowser extends AbstractClientActivity
56 {
57 private static final String TAG = "nxclient/ConnectionPointBrowser";
58 private static final String CPLIST_KEY = "ConnectionPointList";
59 private final int maxConnectionPoints = 50;
60 private List<String> cpList = new ArrayList<String>(0);
61 private EditText editText;
62 private ListView listView;
63 private ConnectionPointListAdapter adapter;
64 private int nodeId = 0;
65 private ProgressDialog dialog;
66 private Resources r;
67
68 /* (non-Javadoc)
69 * @see org.netxms.ui.android.main.activities.AbstractClientActivity#onCreateStep2(android.os.Bundle)
70 */
71 @Override
72 protected void onCreateStep2(Bundle savedInstanceState)
73 {
74 dialog = new ProgressDialog(this);
75 r = getResources();
76 setContentView(R.layout.connection_point_view);
77
78 TextView title = (TextView)findViewById(R.id.ScreenTitlePrimary);
79 title.setText(R.string.connection_point_title);
80 // keeps current list of alarms as datasource for listview
81 adapter = new ConnectionPointListAdapter(this);
82 listView = (ListView)findViewById(R.id.ConnectionPointList);
83 listView.setAdapter(adapter);
84 registerForContextMenu(listView);
85
86 editText = (EditText)findViewById(R.id.MacAddressToSearch);
87 editText.setOnKeyListener(new OnKeyListener()
88 {
89 @Override
90 public boolean onKey(View v, int keyCode, KeyEvent event)
91 {
92 if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) // If the event is a key-down event on the "enter" button
93 {
94 nodeId = 0;
95 startSearch();
96 return true;
97 }
98 return false;
99 }
100 });
101
102 final Button scanButton = (Button)findViewById(R.id.ScanBarcode);
103 scanButton.setOnClickListener(new OnClickListener()
104 {
105 @Override
106 public void onClick(View v)
107 {
108 nodeId = 0;
109 BarcodeScannerIntegrator integrator = new BarcodeScannerIntegrator(ConnectionPointBrowser.this);
110 integrator.initiateScan();
111 }
112 });
113
114 nodeId = getIntent().getIntExtra("nodeId", 0);
115 cpList = retrievePreferences(this, CPLIST_KEY, maxConnectionPoints);
116 adapter.setConnectionPoint(cpList);
117 adapter.notifyDataSetChanged();
118 }
119
120 /* (non-Javadoc)
121 * @see android.app.Activity#onActivityResult(int, int, android.content.Intent)
122 */
123 @Override
124 protected void onActivityResult(int requestCode, int resultCode, Intent data)
125 {
126 Log.w(TAG, "onActivityResult: rq=" + requestCode + " result=" + resultCode);
127 BarcodeScannerIntentResult scanResult = BarcodeScannerIntegrator.parseActivityResult(requestCode, resultCode, data);
128 if (scanResult != null)
129 {
130 editText.setText(scanResult.getContents());
131 startSearch();
132 }
133 super.onActivityResult(requestCode, resultCode, data);
134 }
135
136 /* (non-Javadoc)
137 * @see android.content.ServiceConnection#onServiceConnected(android.content.ComponentName, android.os.IBinder)
138 */
139 @Override
140 public void onServiceConnected(ComponentName name, IBinder binder)
141 {
142 super.onServiceConnected(name, binder);
143 if (nodeId != 0)
144 startSearch();
145 }
146
147 /* (non-Javadoc)
148 * @see android.content.ServiceConnection#onServiceDisconnected(android.content.ComponentName)
149 */
150 @Override
151 public void onServiceDisconnected(ComponentName name)
152 {
153 super.onServiceDisconnected(name);
154 }
155
156 /* (non-Javadoc)
157 * @see android.app.Activity#onCreateContextMenu(android.view.ContextMenu, android.view.View, android.view.ContextMenu.ContextMenuInfo)
158 */
159 @Override
160 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)
161 {
162 android.view.MenuInflater inflater = getMenuInflater();
163 inflater.inflate(R.menu.connection_point_actions, menu);
164 }
165
166 /* (non-Javadoc)
167 * @see android.app.Activity#onContextItemSelected(android.view.MenuItem)
168 */
169 @Override
170 public boolean onContextItemSelected(MenuItem item)
171 {
172 // get selected item
173 AdapterView.AdapterContextMenuInfo info = (AdapterContextMenuInfo)item.getMenuInfo();
174 final int position = info.position;
175
176 if (item.getItemId() == R.id.connection_point_delete_one)
177 {
178 new AlertDialog.Builder(this)
179 .setIcon(android.R.drawable.ic_dialog_alert)
180 .setTitle(R.string.confirm_tool_execution)
181 .setMessage(r.getString(R.string.connection_point_confirm_delete_one))
182 .setCancelable(true)
183 .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener()
184 {
185 @Override
186 public void onClick(DialogInterface dialog, int which)
187 {
188 cpList.remove(position);
189 refreshList();
190 }
191 })
192 .setNegativeButton(R.string.no, null)
193 .show();
194 }
195 else if (item.getItemId() == R.id.connection_point_delete_all)
196 {
197 new AlertDialog.Builder(this)
198 .setIcon(android.R.drawable.ic_dialog_alert)
199 .setTitle(R.string.confirm_tool_execution)
200 .setMessage(r.getString(R.string.connection_point_confirm_delete_all))
201 .setCancelable(true)
202 .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener()
203 {
204 @Override
205 public void onClick(DialogInterface dialog, int which)
206 {
207 cpList.clear();
208 refreshList();
209 }
210 })
211 .setNegativeButton(R.string.no, null)
212 .show();
213 }
214 else
215 {
216 return super.onContextItemSelected(item);
217 }
218 return true;
219 }
220
221 /* (non-Javadoc)
222 * @see android.app.Activity#onDestroy()
223 */
224 @Override
225 protected void onDestroy()
226 {
227 super.onDestroy();
228 }
229
230 /* (non-Javadoc)
231 * @see android.app.Activity#onStop()
232 */
233 @Override
234 protected void onStop()
235 {
236 super.onStop();
237 storePreferences(this, CPLIST_KEY, cpList, maxConnectionPoints);
238 }
239
240 private void refreshList()
241 {
242 adapter.setConnectionPoint(cpList);
243 adapter.notifyDataSetChanged();
244 }
245
246 /**
247 * Store connection points result list
248 */
249 private void storePreferences(Context context, String key, List<String> values, int maxValues)
250 {
251 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
252 SharedPreferences.Editor editor = prefs.edit();
253 JSONArray a = new JSONArray();
254 for (int i = 0; i < Math.min(values.size(), maxValues); i++)
255 a.put(values.get(i));
256 if (!values.isEmpty())
257 editor.putString(key, a.toString());
258 else
259 editor.putString(key, null);
260 editor.commit();
261 }
262
263 /**
264 * Retrieve connection points result list
265 */
266 private ArrayList<String> retrievePreferences(Context context, String key, int maxValues)
267 {
268 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
269 String json = prefs.getString(key, null);
270 ArrayList<String> values = new ArrayList<String>();
271 if (json != null)
272 try
273 {
274 JSONArray a = new JSONArray(json);
275 for (int i = 0; i < Math.min(a.length(), maxValues); i++)
276 values.add(a.optString(i));
277 }
278 catch (JSONException e)
279 {
280 e.printStackTrace();
281 }
282 return values;
283 }
284
285 /**
286 * Start MAC address search
287 */
288 private void startSearch()
289 {
290 new SearchConnectionPointTask(nodeId, editText.getText().toString()).execute();
291 }
292
293 /**
294 * Internal task for loading info for MAC address search
295 */
296 private class SearchConnectionPointTask extends AsyncTask<Object, Void, String>
297 {
298 private final int nodeId;
299 private final String macAddress;
300
301 SearchConnectionPointTask(int nodeId, String macAddress)
302 {
303 this.nodeId = nodeId;
304 this.macAddress = macAddress;
305 }
306
307 /* (non-Javadoc)
308 * @see android.os.AsyncTask#onPreExecute()
309 */
310 @Override
311 protected void onPreExecute()
312 {
313 dialog.setMessage(getString(R.string.progress_gathering_data));
314 dialog.setIndeterminate(true);
315 dialog.setCancelable(false);
316 dialog.show();
317 }
318
319 /* (non-Javadoc)
320 * @see android.os.AsyncTask#doInBackground(Params[])
321 */
322 @Override
323 protected String doInBackground(Object... params)
324 {
325 String string = nodeId != 0 ? r.getString(R.string.connection_point_notfound) : r.getString(R.string.connection_point_macaddress_notfound, macAddress);
326 if (service != null)
327 {
328 NXCSession session = service.getSession();
329 if (session != null)
330 {
331 ConnectionPoint cp = null;
332 Node host = null;
333 Node bridge = null;
334 Interface iface = null;
335 try
336 {
337 cp = nodeId != 0 ? session.findConnectionPoint(nodeId) : session.findConnectionPoint(MacAddress.parseMacAddress(macAddress));
338 if (cp != null)
339 {
340 session.syncMissingObjects(new long[] { cp.getLocalNodeId(), cp.getNodeId(), cp.getInterfaceId() }, false, NXCSession.OBJECT_SYNC_WAIT);
341 host = (Node)session.findObjectById(cp.getLocalNodeId());
342 bridge = (Node)session.findObjectById(cp.getNodeId());
343 iface = (Interface)session.findObjectById(cp.getInterfaceId());
344 }
345 else
346 {
347 session.syncMissingObjects(new long[] { nodeId }, false, NXCSession.OBJECT_SYNC_WAIT);
348 host = (Node)session.findObjectById(nodeId);
349 }
350 }
351 catch (MacAddressFormatException e)
352 {
353 Log.e(TAG, "MacAddressFormatException while executing searchMacAddress", e);
354 string = r.getString(R.string.connection_point_invalid, macAddress);
355 }
356 catch (NXCException e)
357 {
358 Log.e(TAG, "NXCException while executing syncMissingObjects", e);
359 }
360 catch (IOException e)
361 {
362 Log.e(TAG, "IOException while executing syncMissingObjects", e);
363 }
364
365 if ((bridge != null) && (iface != null))
366 string = r.getString(R.string.connection_point_info, host != null ? " " + host.getObjectName() : "", cp.getLocalMacAddress().toString(), bridge.getObjectName(), iface.getObjectName());
367 else if (host != null)
368 string = r.getString(R.string.connection_point_nodeid_notfound, host.getObjectName());
369 }
370 }
371 return string;
372 }
373
374 /* (non-Javadoc)
375 * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
376 */
377 @Override
378 protected void onPostExecute(String result)
379 {
380 dialog.cancel();
381 if (result != null)
382 {
383 cpList.add(0, result);
384 if (cpList.size() > maxConnectionPoints)
385 cpList.remove(maxConnectionPoints);
386 refreshList();
387 }
388 }
389 }
390 }