51fd67925c55fe9dda6cab028bd788d7eb6181a6
[public/netxms.git] / android / src / console / src / org / netxms / ui / android / main / adapters / AlarmListAdapter.java
1 /**
2 *
3 */
4 package org.netxms.ui.android.main.adapters;
5
6 import java.text.DateFormat;
7 import java.util.ArrayList;
8 import java.util.Arrays;
9 import java.util.Collections;
10 import java.util.Comparator;
11 import java.util.List;
12
13 import org.netxms.client.events.Alarm;
14 import org.netxms.client.objects.AbstractObject;
15 import org.netxms.ui.android.R;
16 import org.netxms.ui.android.main.views.CheckableLinearLayout;
17 import org.netxms.ui.android.service.ClientConnectorService;
18
19 import android.app.ProgressDialog;
20 import android.content.Context;
21 import android.content.res.Resources;
22 import android.os.AsyncTask;
23 import android.view.Gravity;
24 import android.view.View;
25 import android.view.ViewGroup;
26 import android.widget.BaseAdapter;
27 import android.widget.ImageView;
28 import android.widget.LinearLayout;
29 import android.widget.TextView;
30
31 /**
32 * Adapter for alarm list
33 *
34 * @author Victor Kirhenshtein
35 * @author Marco Incalcaterra (marco.incalcaterra@thinksoft.it)
36 *
37 */
38
39 public class AlarmListAdapter extends BaseAdapter
40 {
41 public static final int SORT_SEVERITY_ASC = 0;
42 public static final int SORT_SEVERITY_DESC = 1;
43 public static final int SORT_DATE_ASC = 2;
44 public static final int SORT_DATE_DESC = 3;
45 public static final int SORT_NAME_ASC = 4;
46 public static final int SORT_NAME_DESC = 5;
47 public static final int ACKNOWLEDGE = 0;
48 public static final int STICKY_ACKNOWLEDGE = 1;
49 public static final int RESOLVE = 2;
50 public static final int TERMINATE = 3;
51
52 private final Context context;
53 private final List<Alarm> alarms = new ArrayList<Alarm>(0);
54 private ArrayList<Integer> nodeIdList = null;
55 private ClientConnectorService service = null;
56 private int sortBy = SORT_SEVERITY_DESC;
57 private String NODE_UNKNOWN = "";
58 private final ProgressDialog dialog;
59 private final Resources r;
60
61 /**
62 *
63 * @param context
64 */
65 public AlarmListAdapter(Context context)
66 {
67 this.context = context;
68 r = context.getResources();
69 NODE_UNKNOWN = r.getString(R.string.node_unknown);
70 dialog = new ProgressDialog(context);
71 }
72
73 /**
74 *
75 * @param sortBy
76 */
77 public void setSortBy(int sortBy)
78 {
79 this.sortBy = sortBy;
80 }
81
82 /**
83 *
84 * @return
85 */
86 public int getSortBy()
87 {
88 return sortBy;
89 }
90
91 /**
92 * Set alarms filter
93 *
94 * @param list List of nodes to be used to filter alarms
95 */
96 public void setFilter(ArrayList<Integer> list)
97 {
98 nodeIdList = list;
99 }
100
101 /**
102 * Set values to the adapter
103 *
104 * @param values List of alarms
105 */
106 public void setValues(Alarm[] values)
107 {
108 alarms.clear();
109 if (values != null)
110 {
111 if (nodeIdList == null || nodeIdList.size() == 0)
112 alarms.addAll(Arrays.asList(values));
113 else
114 { // Filter on specific node
115 for (int i = 0; i < values.length; i++)
116 for (int j = 0; j < nodeIdList.size(); j++)
117 if (values[i].getSourceObjectId() == nodeIdList.get(j))
118 alarms.add(values[i]);
119 }
120 sort();
121 }
122 }
123
124 /**
125 * Sort the list of alarms
126 */
127 public void sort()
128 {
129 Collections.sort(alarms, new Comparator<Alarm>()
130 {
131 @Override
132 public int compare(Alarm alarm1, Alarm alarm2)
133 {
134 switch (sortBy)
135 {
136 case SORT_SEVERITY_ASC:
137 return compareSeverity(alarm1, alarm2);
138 case SORT_SEVERITY_DESC:
139 return compareSeverity(alarm2, alarm1);
140 case SORT_DATE_ASC:
141 return compareDate(alarm1, alarm2);
142 case SORT_DATE_DESC:
143 return compareDate(alarm2, alarm1);
144 case SORT_NAME_ASC:
145 return compareName(alarm1, alarm2);
146 case SORT_NAME_DESC:
147 return compareName(alarm2, alarm1);
148 }
149 return 1;
150 }
151 });
152 }
153
154 /**
155 * Compare by alarm severity
156 *
157 * @param alarm1 First obj to compare
158 * @param alarm2 Second obj to compare
159 */
160 private int compareSeverity(Alarm alarm1, Alarm alarm2)
161 {
162 int rc = 0;
163 if (alarm1 != null && alarm2 != null)
164 {
165 rc = alarm1.getCurrentSeverity().compareTo(alarm2.getCurrentSeverity());
166 if (rc == 0)
167 {
168 rc = (int)(alarm1.getSourceObjectId() - alarm2.getSourceObjectId());
169 if (rc == 0)
170 {
171 rc = compareDate(alarm1, alarm2);
172 if (rc == 0)
173 rc = alarm1.getState() - alarm2.getState();
174 }
175 }
176 }
177 return rc;
178 }
179
180 /**
181 * Compare by alarm date
182 *
183 * @param alarm1 First obj to compare
184 * @param alarm2 Second obj to compare
185 */
186 private int compareDate(Alarm alarm1, Alarm alarm2)
187 {
188 int rc = 0;
189 if (alarm1 != null && alarm2 != null)
190 rc = alarm1.getLastChangeTime().compareTo(alarm2.getLastChangeTime());
191 return rc;
192 }
193
194 /**
195 * Compare by alarm's node name
196 *
197 * @param alarm1 First obj to compare
198 * @param alarm2 Second obj to compare
199 */
200 private int compareName(Alarm alarm1, Alarm alarm2)
201 {
202 int rc = 0;
203 if (alarm1 != null && alarm2 != null)
204 rc = getObjectName(alarm1.getSourceObjectId()).compareTo(getObjectName(alarm2.getSourceObjectId()));
205 return rc;
206 }
207
208 /**
209 * @param objectId
210 * @return
211 */
212 private String getObjectName(long objectId)
213 {
214 AbstractObject object = null;
215 if (service != null)
216 object = service.findObjectById(objectId);
217 return object == null ? NODE_UNKNOWN : object.getObjectName();
218 }
219
220 /**
221 * @param service
222 */
223 public void setService(ClientConnectorService service)
224 {
225 this.service = service;
226 }
227
228 /*
229 * (non-Javadoc)
230 *
231 * @see android.widget.Adapter#getCount()
232 */
233 @Override
234 public int getCount()
235 {
236 return alarms.size();
237 }
238
239 /*
240 * (non-Javadoc)
241 *
242 * @see android.widget.Adapter#getItem(int)
243 */
244 @Override
245 public Object getItem(int position)
246 {
247 if (position >= 0 && position < getCount())
248 return alarms.get(position);
249 return null;
250 }
251
252 /*
253 * (non-Javadoc)
254 *
255 * @see android.widget.Adapter#getItemId(int)
256 */
257 @Override
258 public long getItemId(int position)
259 {
260 if (position >= 0 && position < getCount())
261 return alarms.get(position).getId();
262 return 0;
263 }
264
265 /**
266 * @param action Action to be executed
267 * @param ids List of id to be processed
268 */
269
270 @SuppressWarnings("unchecked")
271 public void doAction(int action, ArrayList<Long> ids)
272 {
273 if (ids.size() > 0)
274 new AlarmActionTask(action).execute(ids);
275 }
276
277 /*
278 * (non-Javadoc)
279 *
280 * @see android.widget.Adapter#getView(int, android.view.View,
281 * android.view.ViewGroup)
282 */
283 @Override
284 public View getView(int position, View convertView, ViewGroup parent)
285 {
286 TextView message, source, date;
287 LinearLayout view, texts, info, icons;
288 ImageView severity, state;
289
290 if (convertView == null) // new alarm, create fields
291 {
292 severity = new ImageView(context);
293 severity.setPadding(5, 5, 5, 2);
294 state = new ImageView(context);
295 state.setPadding(5, 5, 5, 2);
296 icons = new LinearLayout(context);
297 icons.setOrientation(LinearLayout.VERTICAL);
298 icons.addView(severity);
299 icons.addView(state);
300
301 source = new TextView(context);
302 source.setPadding(5, 2, 5, 2);
303 source.setTextColor(r.getColor(R.color.text_color));
304 date = new TextView(context);
305 date.setPadding(5, 2, 5, 2);
306 date.setTextColor(r.getColor(R.color.text_color));
307 date.setGravity(Gravity.RIGHT);
308 LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
309 lp.gravity = Gravity.RIGHT;
310 date.setLayoutParams(lp);
311 message = new TextView(context);
312 message.setPadding(5, 2, 5, 2);
313 message.setTextColor(r.getColor(R.color.text_color));
314 info = new LinearLayout(context);
315 info.setOrientation(LinearLayout.HORIZONTAL);
316 info.addView(source);
317 info.addView(date);
318 texts = new LinearLayout(context);
319 texts.setOrientation(LinearLayout.VERTICAL);
320 lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
321 texts.setLayoutParams(lp);
322 texts.addView(info);
323 texts.addView(message);
324
325 view = new CheckableLinearLayout(context);
326 view.addView(icons);
327 view.addView(texts);
328 }
329 else
330 {
331 // get reference to existing alarm
332 view = (CheckableLinearLayout)convertView;
333 icons = (LinearLayout)view.getChildAt(1);
334 severity = (ImageView)icons.getChildAt(0);
335 state = (ImageView)icons.getChildAt(1);
336 texts = (LinearLayout)view.getChildAt(2);
337 info = (LinearLayout)texts.getChildAt(0);
338 source = (TextView)info.getChildAt(0);
339 date = (TextView)info.getChildAt(1);
340 message = (TextView)texts.getChildAt(1);
341 }
342
343 // get node name
344 Alarm alarm = alarms.get(position);
345 source.setText(getObjectName(alarm.getSourceObjectId()));
346 date.setText(DateFormat.getDateTimeInstance().format(alarm.getLastChangeTime()));
347 message.setText(alarm.getMessage());
348 severity.setImageResource(getAlarmIconSeverity(alarm));
349 state.setImageResource(getAlarmIconState(alarm));
350
351 return view;
352 }
353
354 private int getAlarmIconSeverity(Alarm alarm)
355 {
356 final int[] severityImageId = { R.drawable.status_normal, R.drawable.status_warning,
357 R.drawable.status_minor, R.drawable.status_major, R.drawable.status_critical };
358 return severityImageId[alarm.getCurrentSeverity().getValue()];
359
360 }
361 private int getAlarmIconState(Alarm alarm)
362 {
363 final int[] stateImageId = { R.drawable.alarm_outstanding, R.drawable.alarm_acknowledged,
364 R.drawable.alarm_resolved, R.drawable.alarm_terminated };
365 return alarm.isSticky() ? R.drawable.alarm_sticky_acknowledged : stateImageId[alarm.getState()];
366 }
367
368 /**
369 * Internal task for taking action on list of alarms selected
370 */
371 private class AlarmActionTask extends AsyncTask<ArrayList<Long>, Void, Void>
372 {
373 private final int action;
374
375 protected AlarmActionTask(int action)
376 {
377 this.action = action;
378 }
379
380 @Override
381 protected void onPreExecute()
382 {
383 dialog.setMessage(r.getString(R.string.progress_processing_data));
384 dialog.setIndeterminate(true);
385 dialog.setCancelable(false);
386 dialog.show();
387 }
388
389 @Override
390 protected Void doInBackground(ArrayList<Long>... params)
391 {
392 if (service != null)
393 switch (action)
394 {
395 case ACKNOWLEDGE:
396 service.acknowledgeAlarms(params[0], false);
397 break;
398 case STICKY_ACKNOWLEDGE:
399 service.acknowledgeAlarms(params[0], true);
400 break;
401 case RESOLVE:
402 service.resolveAlarms(params[0]);
403 break;
404 case TERMINATE:
405 service.terminateAlarms(params[0]);
406 break;
407 }
408 return null;
409 }
410
411 @Override
412 protected void onPostExecute(Void result)
413 {
414 if (service != null)
415 {
416 setValues(service.getAlarms());
417 notifyDataSetChanged();
418 }
419 dialog.cancel();
420 }
421 }
422 }