Fix for Jira IOT-1044.
[platform/upstream/iotivity.git] / service / simulator / java / eclipse-plugin / ClientControllerPlugin / src / oic / simulator / clientcontroller / view / AttributeEditingSupport.java
1 /*
2  * Copyright 2015 Samsung Electronics All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package oic.simulator.clientcontroller.view;
18
19 import org.eclipse.jface.dialogs.TitleAreaDialog;
20 import org.eclipse.jface.viewers.CellEditor;
21 import org.eclipse.jface.viewers.CheckboxCellEditor;
22 import org.eclipse.jface.viewers.ComboBoxCellEditor;
23 import org.eclipse.jface.viewers.EditingSupport;
24 import org.eclipse.jface.viewers.TextCellEditor;
25 import org.eclipse.jface.viewers.TreeViewer;
26 import org.eclipse.jface.window.Window;
27 import org.eclipse.swt.SWT;
28 import org.eclipse.swt.custom.CCombo;
29 import org.eclipse.swt.events.ModifyEvent;
30 import org.eclipse.swt.events.ModifyListener;
31 import org.eclipse.swt.widgets.Display;
32 import org.eclipse.swt.widgets.MessageBox;
33 import org.eclipse.swt.widgets.Text;
34 import org.eclipse.swt.widgets.Tree;
35 import org.eclipse.swt.widgets.TreeItem;
36
37 import java.util.Date;
38 import java.util.List;
39
40 import org.oic.simulator.ArrayProperty;
41 import org.oic.simulator.AttributeProperty;
42 import org.oic.simulator.AttributeValue;
43 import org.oic.simulator.AttributeValue.TypeInfo;
44 import org.oic.simulator.AttributeValue.ValueType;
45 import org.oic.simulator.ILogger.Level;
46 import org.oic.simulator.InvalidArgsException;
47 import org.oic.simulator.SimulatorResourceAttribute;
48
49 import oic.simulator.clientcontroller.Activator;
50 import oic.simulator.clientcontroller.manager.ResourceManager;
51 import oic.simulator.clientcontroller.remoteresource.AttributeElement;
52 import oic.simulator.clientcontroller.remoteresource.RemoteResource;
53 import oic.simulator.clientcontroller.remoteresource.ResourceRepresentation;
54 import oic.simulator.clientcontroller.utils.AttributeValueBuilder;
55 import oic.simulator.clientcontroller.utils.Utility;
56 import oic.simulator.clientcontroller.view.dialogs.PostRequestDialog;
57 import oic.simulator.clientcontroller.view.dialogs.UpdatePrimitiveArrayAttributeDialog;
58
59 /**
60  * This class provides editing support to the resources attributes table in the
61  * attributes view.
62  */
63 public class AttributeEditingSupport {
64
65     private AttributeValueEditor attValueEditor;
66     private PostSelectionEditor  postSelectionEditor;
67
68     public AttributeValueEditor createAttributeValueEditor(TreeViewer viewer,
69             TitleAreaDialog dialog) {
70         attValueEditor = new AttributeValueEditor(viewer, dialog);
71         return attValueEditor;
72     }
73
74     public PostSelectionEditor createPostSelectionEditor(TreeViewer viewer) {
75         postSelectionEditor = new PostSelectionEditor(viewer);
76         return postSelectionEditor;
77     }
78
79     class AttributeValueEditor extends EditingSupport {
80
81         private final TreeViewer viewer;
82         private CCombo           comboBox;
83         private TitleAreaDialog  dialog;
84
85         public AttributeValueEditor(TreeViewer viewer, TitleAreaDialog dialog) {
86             super(viewer);
87             this.viewer = viewer;
88             this.dialog = dialog;
89         }
90
91         @Override
92         protected boolean canEdit(Object arg0) {
93             return true;
94         }
95
96         @Override
97         protected CellEditor getCellEditor(final Object element) {
98             ResourceManager resourceManager = Activator.getDefault()
99                     .getResourceManager();
100
101             RemoteResource res = resourceManager
102                     .getCurrentResourceInSelection();
103             if (null == res) {
104                 return null;
105             }
106
107             final SimulatorResourceAttribute attribute;
108             if (!(element instanceof AttributeElement)) {
109                 return null;
110             }
111
112             final AttributeElement attributeElement = ((AttributeElement) element);
113             attribute = attributeElement.getSimulatorResourceAttribute();
114             if (null == attribute) {
115                 return null;
116             }
117
118             final AttributeValue val = attribute.value();
119             if (null == val) {
120                 return null;
121             }
122
123             final TypeInfo type = val.typeInfo();
124             if (type.mBaseType == ValueType.RESOURCEMODEL) {
125                 return null;
126             }
127
128             CellEditor editor;
129             if (type.mType == ValueType.ARRAY && res.isConfigUploaded()
130                     && isArrayAttributeValid(attribute)) {
131                 editor = new TextCellEditor(viewer.getTree());
132                 editor.setStyle(SWT.READ_ONLY);
133                 final Text txt = (Text) editor.getControl();
134                 txt.addModifyListener(new ModifyListener() {
135                     @Override
136                     public void modifyText(ModifyEvent e) {
137                         UpdatePrimitiveArrayAttributeDialog dialog = new UpdatePrimitiveArrayAttributeDialog(
138                                 Display.getDefault().getActiveShell(),
139                                 attribute);
140                         if (dialog.open() == Window.OK) {
141                             updateAttributeValue(attributeElement, attribute,
142                                     dialog.getNewValueObj());
143                         }
144
145                         // Update the viewer in a separate UI thread.
146                         Display.getDefault().asyncExec(new Runnable() {
147                             @Override
148                             public void run() {
149                                 // Set the post state of the top-level
150                                 // attribute.
151                                 AttributeElement rootElement = getRootElement(attributeElement);
152                                 rootElement.setPostState(true);
153                                 viewer.refresh(rootElement, true);
154                             }
155                         });
156                     }
157                 });
158             } else {
159                 String values[] = null;
160                 List<String> valueSet = resourceManager
161                         .getAllValuesOfAttribute(attribute);
162                 values = convertListToStringArray(valueSet);
163
164                 editor = new ComboBoxCellEditor(viewer.getTree(), values);
165                 comboBox = (CCombo) editor.getControl();
166                 comboBox.addModifyListener(new ModifyListener() {
167
168                     @Override
169                     public void modifyText(ModifyEvent event) {
170                         // Set the post state of the top-level attribute.
171                         AttributeElement rootElement = getRootElement(attributeElement);
172                         rootElement.setPostState(true);
173                         if (AttributeValueEditor.this.dialog instanceof PostRequestDialog) {
174                             viewer.update(rootElement, null);
175                         }
176                     }
177                 });
178             }
179             return editor;
180         }
181
182         @Override
183         protected Object getValue(Object element) {
184             int indexOfItem = 0;
185             SimulatorResourceAttribute att = null;
186
187             if (element instanceof AttributeElement) {
188                 att = ((AttributeElement) element)
189                         .getSimulatorResourceAttribute();
190             }
191
192             if (att == null) {
193                 return 0;
194             }
195
196             final AttributeValue val = att.value();
197             if (null == val) {
198                 return null;
199             }
200
201             final TypeInfo type = val.typeInfo();
202             if (type.mBaseType == ValueType.RESOURCEMODEL) {
203                 return null;
204             }
205
206             String valueString = Utility.getAttributeValueAsString(att.value());
207             if (null == valueString) {
208                 valueString = "";
209             }
210
211             if (type.mType == ValueType.ARRAY) {
212                 ResourceManager resourceManager = Activator.getDefault()
213                         .getResourceManager();
214
215                 RemoteResource res = resourceManager
216                         .getCurrentResourceInSelection();
217                 if (null != res && res.isConfigUploaded()
218                         && isArrayAttributeValid(att)) {
219                     return valueString;
220                 }
221             }
222
223             List<String> valueSet = Activator.getDefault().getResourceManager()
224                     .getAllValuesOfAttribute(att);
225             if (null != valueSet) {
226                 indexOfItem = valueSet.indexOf(valueString);
227             }
228             if (indexOfItem == -1) {
229                 indexOfItem = 0;
230             }
231             return indexOfItem;
232         }
233
234         @Override
235         protected void setValue(Object element, Object value) {
236             SimulatorResourceAttribute att = null;
237             if (element instanceof AttributeElement) {
238                 att = ((AttributeElement) element)
239                         .getSimulatorResourceAttribute();
240             }
241
242             if (att == null) {
243                 return;
244             }
245
246             AttributeValue val = att.value();
247             if (null == val) {
248                 return;
249             }
250
251             TypeInfo type = val.typeInfo();
252
253             if (type.mBaseType == ValueType.RESOURCEMODEL) {
254                 return;
255             }
256
257             if (type.mType == ValueType.ARRAY) {
258                 ResourceManager resourceManager = Activator.getDefault()
259                         .getResourceManager();
260
261                 RemoteResource res = resourceManager
262                         .getCurrentResourceInSelection();
263                 if (null != res && res.isConfigUploaded()
264                         && isArrayAttributeValid(att)) {
265                     return;
266                 }
267             }
268
269             String oldValue = String.valueOf(Utility
270                     .getAttributeValueAsString(val));
271             if (null == oldValue) {
272                 oldValue = "";
273             }
274
275             String newValue = comboBox.getText();
276
277             if (type.mType == ValueType.ARRAY
278                     && type.mBaseType != ValueType.RESOURCEMODEL) {
279                 newValue = Utility.removeWhiteSpacesInArrayValues(newValue);
280             }
281
282             if (!oldValue.equals(newValue)) {
283                 boolean invalid = false;
284
285                 // Get the AttriuteValue from the string
286                 AttributeValue attValue = null;
287                 try {
288                     attValue = AttributeValueBuilder.build(newValue,
289                             type.mBaseType);
290                 } catch (Exception e) {
291                     Activator
292                             .getDefault()
293                             .getLogManager()
294                             .log(Level.ERROR.ordinal(),
295                                     new Date(),
296                                     "There is an error while creating the new attribute value.\n"
297                                             + Utility.getSimulatorErrorString(
298                                                     e, null));
299                 }
300                 if (null == attValue) {
301                     invalid = true;
302                 } else {
303                     TypeInfo resTypeInfo = attValue.typeInfo();
304                     if (type.mDepth != resTypeInfo.mDepth
305                             || type.mType != resTypeInfo.mType
306                             || type.mBaseType != resTypeInfo.mBaseType) {
307                         invalid = true;
308                     }
309                 }
310                 if (invalid) {
311                     MessageBox dialog = new MessageBox(viewer.getTree()
312                             .getShell(), SWT.ICON_ERROR | SWT.OK);
313                     dialog.setText("Invalid Value");
314                     dialog.setMessage("Given value is invalid");
315                     dialog.open();
316                 } else {
317                     updateAttributeValue((AttributeElement) element, att,
318                             attValue);
319                 }
320             }
321
322             viewer.update(element, null);
323         }
324
325         private boolean isArrayAttributeValid(
326                 SimulatorResourceAttribute attribute) {
327             if (null == attribute)
328                 return false;
329
330             AttributeValue val = attribute.value();
331             if (null == val)
332                 return false;
333
334             AttributeProperty prop = attribute.property();
335             if (null == prop || !prop.isArray())
336                 return false;
337
338             ArrayProperty arrProp = prop.asArray();
339             if (null == arrProp)
340                 return false;
341
342             AttributeProperty elementProp = arrProp.getElementProperty();
343             if (null == elementProp)
344                 return false;
345
346             TypeInfo info = val.typeInfo();
347             if (info.mBaseType == ValueType.RESOURCEMODEL)
348                 return false;
349
350             return true;
351         }
352
353         public String[] convertListToStringArray(List<String> values) {
354             String[] strArr;
355             if (null != values && values.size() > 0) {
356                 strArr = values.toArray(new String[1]);
357             } else {
358                 strArr = new String[1];
359             }
360             return strArr;
361         }
362
363         public void updateAttributeValue(AttributeElement attributeElement,
364                 SimulatorResourceAttribute att, AttributeValue value) {
365             // Update the post status.
366             Object parent = attributeElement.getParent();
367             AttributeElement rootElement = attributeElement;
368             while (parent != null && parent instanceof AttributeElement) {
369                 rootElement = (AttributeElement) parent;
370                 parent = ((AttributeElement) parent).getParent();
371             }
372             rootElement.setPostState(true);
373
374             // Set the attribute value.
375             attributeElement.getSimulatorResourceAttribute().setValue(value);
376
377             // Update the hierarchy.
378             parent = attributeElement.getParent();
379             if (null != parent && parent instanceof AttributeElement) {
380                 try {
381                     ((AttributeElement) parent).deepSetChildValue(att);
382                 } catch (InvalidArgsException e) {
383                     e.printStackTrace();
384                 }
385             }
386         }
387     }
388
389     class PostSelectionEditor extends EditingSupport {
390
391         private final TreeViewer viewer;
392
393         public PostSelectionEditor(TreeViewer viewer) {
394             super(viewer);
395             this.viewer = viewer;
396         }
397
398         @Override
399         protected boolean canEdit(Object arg0) {
400             return true;
401         }
402
403         @Override
404         protected CellEditor getCellEditor(Object element) {
405             if (element instanceof AttributeElement
406                     && ((AttributeElement) element).getParent() instanceof ResourceRepresentation) {
407                 return new CheckboxCellEditor(null, SWT.CHECK | SWT.READ_ONLY);
408             }
409
410             return null;
411         }
412
413         @Override
414         protected Object getValue(Object element) {
415             if (element instanceof AttributeElement) {
416                 return ((AttributeElement) element).getPostState();
417             }
418
419             return false;
420         }
421
422         @Override
423         protected void setValue(Object element, Object value) {
424             if (!(element instanceof AttributeElement)) {
425                 return;
426             }
427
428             boolean status = (Boolean) value;
429             ((AttributeElement) element).setPostState(status);
430             viewer.update(element, null);
431
432             Tree t = viewer.getTree();
433             TreeItem item = t.getSelection()[0];
434             if (null == item) {
435                 return;
436             }
437
438             // Update the post state of the top-most parent of this attribute.
439             TreeItem parent = item.getParentItem();
440             if (null != parent) {
441                 while (parent.getParentItem() != null) {
442                     parent = parent.getParentItem();
443                 }
444                 Object data = parent.getData();
445                 ((AttributeElement) data).setPostState(status);
446             }
447         }
448     }
449
450     private AttributeElement getRootElement(AttributeElement element) {
451         AttributeElement root = null;
452
453         Object parent = element.getParent();
454         if (parent instanceof ResourceRepresentation) {
455             return element;
456         }
457
458         while (!(parent instanceof ResourceRepresentation)) {
459             root = (AttributeElement) parent;
460             parent = ((AttributeElement) parent).getParent();
461         }
462
463         return root;
464     }
465 }