[IoTivity Simulator] Handling resource interfaces.
[platform/upstream/iotivity.git] / service / simulator / java / eclipse-plugin / ServiceProviderPlugin / src / oic / simulator / serviceprovider / view / MetaPropertiesView.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.serviceprovider.view;
18
19 import java.util.HashMap;
20 import java.util.Iterator;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Set;
24
25 import oic.simulator.serviceprovider.Activator;
26 import oic.simulator.serviceprovider.listener.ISelectionChangedListener;
27 import oic.simulator.serviceprovider.manager.ResourceManager;
28 import oic.simulator.serviceprovider.manager.UiListenerHandler;
29 import oic.simulator.serviceprovider.model.MetaProperty;
30 import oic.simulator.serviceprovider.model.Resource;
31 import oic.simulator.serviceprovider.model.SingleResource;
32 import oic.simulator.serviceprovider.utils.Constants;
33 import oic.simulator.serviceprovider.utils.Utility;
34 import oic.simulator.serviceprovider.view.dialogs.UpdateResourceInterfaceDialog;
35
36 import org.eclipse.jface.dialogs.MessageDialog;
37 import org.eclipse.jface.viewers.CellEditor;
38 import org.eclipse.jface.viewers.EditingSupport;
39 import org.eclipse.jface.viewers.IStructuredContentProvider;
40 import org.eclipse.jface.viewers.StyledCellLabelProvider;
41 import org.eclipse.jface.viewers.TableViewer;
42 import org.eclipse.jface.viewers.TableViewerColumn;
43 import org.eclipse.jface.viewers.TextCellEditor;
44 import org.eclipse.jface.viewers.Viewer;
45 import org.eclipse.jface.viewers.ViewerCell;
46 import org.eclipse.jface.window.Window;
47 import org.eclipse.swt.SWT;
48 import org.eclipse.swt.events.ModifyEvent;
49 import org.eclipse.swt.events.ModifyListener;
50 import org.eclipse.swt.events.SelectionAdapter;
51 import org.eclipse.swt.events.SelectionEvent;
52 import org.eclipse.swt.layout.GridData;
53 import org.eclipse.swt.layout.GridLayout;
54 import org.eclipse.swt.widgets.Button;
55 import org.eclipse.swt.widgets.Composite;
56 import org.eclipse.swt.widgets.Display;
57 import org.eclipse.swt.widgets.Table;
58 import org.eclipse.swt.widgets.Text;
59 import org.eclipse.ui.part.ViewPart;
60 import org.oic.simulator.SimulatorException;
61
62 /**
63  * This class manages and shows the meta properties view in the perspective.
64  */
65 public class MetaPropertiesView extends ViewPart {
66
67     public static final String        VIEW_ID       = "oic.simulator.serviceprovider.view.metaproperties";
68
69     private TableViewer               tableViewer;
70
71     private final String[]            columnHeaders = { "Property", "Value" };
72
73     private final Integer[]           columnWidth   = { 150, 150 };
74
75     private ISelectionChangedListener resourceSelectionChangedListener;
76
77     private ResourceManager           resourceManagerRef;
78
79     private Set<String>               updatedIfSet;
80
81     private List<MetaProperty>        properties;
82
83     private boolean                   enable_edit;
84     private Button                    editBtn;
85     private Button                    cancelBtn;
86
87     private Map<String, String>       ifTypes;
88
89     public MetaPropertiesView() {
90
91         resourceManagerRef = Activator.getDefault().getResourceManager();
92
93         resourceSelectionChangedListener = new ISelectionChangedListener() {
94
95             @Override
96             public void onResourceSelectionChange(final Resource resource) {
97                 Display.getDefault().asyncExec(new Runnable() {
98
99                     @Override
100                     public void run() {
101                         if (null != tableViewer) {
102                             properties = getData(resource);
103                             updateViewer(properties);
104                         }
105                         updateEditControls(resource);
106                     }
107                 });
108             }
109         };
110     }
111
112     @Override
113     public void createPartControl(final Composite parent) {
114         parent.setLayout(new GridLayout(2, false));
115
116         tableViewer = new TableViewer(parent, SWT.SINGLE | SWT.H_SCROLL
117                 | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
118
119         createColumns(tableViewer);
120
121         // Make lines and header visible
122         final Table table = tableViewer.getTable();
123         GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
124         gd.horizontalSpan = 2;
125         table.setLayoutData(gd);
126         table.setHeaderVisible(true);
127         table.setLinesVisible(true);
128
129         tableViewer.setContentProvider(new PropertycontentProvider());
130
131         editBtn = new Button(parent, SWT.PUSH);
132         editBtn.setText("Edit");
133         gd = new GridData();
134         gd.widthHint = 50;
135         editBtn.setLayoutData(gd);
136         editBtn.addSelectionListener(new SelectionAdapter() {
137             @Override
138             public void widgetSelected(SelectionEvent e) {
139                 if (editBtn.getText().equals("Edit")) {
140                     cancelBtn.setEnabled(true);
141                     editBtn.setText("Save");
142                     setEnableEdit(true);
143
144                     Resource resource = resourceManagerRef
145                             .getCurrentResourceInSelection();
146                     if (null != resource) {
147                         updatedIfSet = resource.getResourceInterfaces();
148                     }
149                 } else {
150                     boolean result = false;
151                     Resource resourceInSelection = resourceManagerRef
152                             .getCurrentResourceInSelection();
153                     if (null != resourceInSelection) {
154
155                         // Null Check
156                         result = resourceManagerRef.isPropertyValueInvalid(
157                                 resourceInSelection, properties,
158                                 Constants.RESOURCE_URI);
159                         if (result) {
160                             MessageDialog.openError(parent.getShell(),
161                                     "Invalid Resource URI.",
162                                     Constants.INVALID_URI_MESSAGE);
163                             return;
164                         }
165
166                         result = resourceManagerRef.isPropertyValueInvalid(
167                                 resourceInSelection, properties,
168                                 Constants.RESOURCE_NAME);
169                         if (result) {
170                             MessageDialog.openError(parent.getShell(),
171                                     "Invalid Input",
172                                     "Resource Name is invalid.");
173                             return;
174                         }
175
176                         boolean update = false;
177                         boolean uriChange = false;
178                         boolean nameChange = false;
179                         boolean interfaceChange = false;
180
181                         if (resourceManagerRef.isPropValueChanged(
182                                 resourceInSelection, properties,
183                                 Constants.RESOURCE_NAME)) {
184                             update = true;
185                             nameChange = true;
186                         }
187                         if (resourceManagerRef.isPropValueChanged(
188                                 resourceInSelection, properties,
189                                 Constants.RESOURCE_URI)) {
190                             // Check whether the new URI is unique.
191                             if (!resourceManagerRef.isUriUnique(properties)) {
192                                 MessageDialog.openError(parent.getShell(),
193                                         "Resource URI in use",
194                                         "Resource URI is in use. Please try a different URI.");
195                                 return;
196                             }
197
198                             if (resourceManagerRef
199                                     .isResourceStarted(resourceInSelection)) {
200                                 update = MessageDialog.openQuestion(
201                                         parent.getShell(), "Save Details",
202                                         "Resource will be restarted to take the changes."
203                                                 + " Do you want to continue?");
204                                 if (!update) {
205                                     return;
206                                 }
207                             }
208
209                             update = true;
210                             uriChange = true;
211                         }
212                         // Checking whether any changes made in resource
213                         // interfaces by
214                         // comparing the current interface set and updated
215                         // interface set.
216                         if (null != updatedIfSet) {
217                             Set<String> curIfSet = resourceInSelection
218                                     .getResourceInterfaces();
219                             if (curIfSet.size() != updatedIfSet.size()) {
220                                 update = true;
221                                 interfaceChange = true;
222                             } else {
223                                 Iterator<String> itr = updatedIfSet.iterator();
224                                 while (itr.hasNext()) {
225                                     if (!curIfSet.contains(itr.next())) {
226                                         update = true;
227                                         interfaceChange = true;
228                                         break;
229                                     }
230                                 }
231                             }
232                         }
233                         if (update) {
234                             try {
235                                 if (uriChange || nameChange)
236                                     result = Activator
237                                             .getDefault()
238                                             .getResourceManager()
239                                             .updateResourceProperties(
240                                                     resourceManagerRef
241                                                             .getCurrentResourceInSelection(),
242                                                     properties, uriChange,
243                                                     nameChange);
244                                 if (interfaceChange)
245                                     result = Activator
246                                             .getDefault()
247                                             .getResourceManager()
248                                             .updateResourceInterfaces(
249                                                     resourceInSelection,
250                                                     updatedIfSet);
251
252                             } catch (SimulatorException ex) {
253                                 result = false;
254                             }
255                             if (result) {
256                                 MessageDialog.openInformation(
257                                         parent.getShell(), "Operation status",
258                                         "Resource properties updated.");
259                             } else {
260                                 MessageDialog.openInformation(
261                                         parent.getShell(), "Operation status",
262                                         "Failed to update the resource properties.");
263
264                                 // Reset the old property values.
265                                 properties = getData(resourceManagerRef
266                                         .getCurrentResourceInSelection());
267                                 updateViewer(properties);
268                             }
269                         }
270                     }
271                     cancelBtn.setEnabled(false);
272                     editBtn.setText("Edit");
273                     setEnableEdit(false);
274                 }
275             }
276         });
277
278         cancelBtn = new Button(parent, SWT.PUSH);
279         cancelBtn.setText("Cancel");
280         cancelBtn.setEnabled(false);
281         gd = new GridData();
282         gd.widthHint = 70;
283         cancelBtn.setLayoutData(gd);
284         cancelBtn.addSelectionListener(new SelectionAdapter() {
285             @Override
286             public void widgetSelected(SelectionEvent e) {
287                 Resource res = resourceManagerRef
288                         .getCurrentResourceInSelection();
289                 if (null != res) {
290                     properties = getData(res);
291                 }
292                 updateViewer(properties);
293
294                 cancelBtn.setEnabled(false);
295                 editBtn.setText("Edit");
296                 setEnableEdit(false);
297                 if (null != updatedIfSet)
298                     updatedIfSet.clear();
299             }
300         });
301
302         // Get the supported interfaces.
303         Map<String, String> ifTypesSupported = Utility
304                 .getResourceInterfaces(SingleResource.class);
305         if (null != ifTypesSupported && !ifTypesSupported.isEmpty()) {
306             ifTypes = new HashMap<String, String>();
307             String key;
308             for (Map.Entry<String, String> entry : ifTypesSupported.entrySet()) {
309                 key = entry.getValue() + " (" + entry.getKey() + ")";
310                 ifTypes.put(key, entry.getKey());
311             }
312         }
313
314         addManagerListeners();
315
316         // Check whether there is any resource selected already
317         Resource resource = resourceManagerRef.getCurrentResourceInSelection();
318         properties = getData(resource);
319         if (null != properties) {
320             updateViewer(properties);
321         }
322         updateEditControls(resource);
323     }
324
325     private void updateEditControls(Object obj) {
326         if (!editBtn.isDisposed() && !cancelBtn.isDisposed()) {
327
328             if (editBtn.getText().equals("Save")) {
329                 editBtn.setText("Edit");
330                 setEnableEdit(false);
331             }
332
333             if (null == obj) {
334                 editBtn.setEnabled(false);
335             } else {
336                 editBtn.setEnabled(true);
337             }
338             cancelBtn.setEnabled(false);
339         }
340     }
341
342     private List<MetaProperty> getData(Resource resource) {
343         if (null != resource) {
344             List<MetaProperty> metaPropertyList = resourceManagerRef
345                     .getMetaProperties(resource);
346             return metaPropertyList;
347         } else {
348             return null;
349         }
350     }
351
352     private void updateViewer(List<MetaProperty> metaPropertyList) {
353         if (null != tableViewer) {
354             Table tbl = tableViewer.getTable();
355             if (tbl.isDisposed()) {
356                 return;
357             }
358             if (null != metaPropertyList) {
359                 tableViewer.setInput(metaPropertyList.toArray());
360                 tbl.setLinesVisible(true);
361             } else {
362                 tbl.removeAll();
363                 tbl.setLinesVisible(false);
364             }
365         }
366     }
367
368     public void createColumns(final TableViewer tableViewer) {
369         TableViewerColumn propName = new TableViewerColumn(tableViewer,
370                 SWT.NONE);
371         propName.getColumn().setWidth(columnWidth[0]);
372         propName.getColumn().setText(columnHeaders[0]);
373         propName.setLabelProvider(new StyledCellLabelProvider() {
374             @Override
375             public void update(ViewerCell cell) {
376                 MetaProperty prop = (MetaProperty) cell.getElement();
377                 cell.setText(prop.getPropName());
378                 super.update(cell);
379             }
380         });
381
382         TableViewerColumn propValue = new TableViewerColumn(tableViewer,
383                 SWT.NONE);
384         propValue.getColumn().setWidth(columnWidth[1]);
385         propValue.getColumn().setText(columnHeaders[1]);
386         propValue.setLabelProvider(new StyledCellLabelProvider() {
387             @Override
388             public void update(ViewerCell cell) {
389                 MetaProperty prop = (MetaProperty) cell.getElement();
390                 cell.setText(prop.getPropValue());
391                 super.update(cell);
392             }
393         });
394         propValue.setEditingSupport(new PropValueEditor(tableViewer));
395     }
396
397     private void addManagerListeners() {
398         UiListenerHandler.getInstance().addResourceSelectionChangedUIListener(
399                 resourceSelectionChangedListener);
400     }
401
402     class PropertycontentProvider implements IStructuredContentProvider {
403
404         @Override
405         public void dispose() {
406         }
407
408         @Override
409         public void inputChanged(Viewer arg0, Object arg1, Object arg2) {
410         }
411
412         @Override
413         public Object[] getElements(Object element) {
414             return (Object[]) element;
415         }
416     }
417
418     @Override
419     public void dispose() {
420         // Unregister the listener
421         if (null != resourceSelectionChangedListener) {
422             UiListenerHandler.getInstance()
423                     .removeResourceSelectionChangedUIListener(
424                             resourceSelectionChangedListener);
425         }
426         super.dispose();
427     }
428
429     class PropValueEditor extends EditingSupport {
430
431         private final TableViewer viewer;
432
433         public PropValueEditor(TableViewer viewer) {
434             super(viewer);
435             this.viewer = viewer;
436         }
437
438         @Override
439         protected boolean canEdit(Object element) {
440             return true;
441         }
442
443         @Override
444         protected CellEditor getCellEditor(final Object element) {
445             if (!getEnableEdit()) {
446                 return null;
447             }
448             // Disabling edit for resource type
449             String propName = ((MetaProperty) element).getPropName();
450             if (null != propName && propName.equals(Constants.RESOURCE_TYPE)) {
451                 return null;
452             }
453
454             CellEditor editor = new TextCellEditor(viewer.getTable());
455             if (null != propName && propName.equals(Constants.INTERFACE_TYPES)) {
456                 editor.setStyle(SWT.READ_ONLY);
457                 final Text txt = (Text) editor.getControl();
458                 txt.addModifyListener(new ModifyListener() {
459                     @Override
460                     public void modifyText(ModifyEvent e) {
461                         if (null == updatedIfSet) {
462                             return;
463                         }
464                         // Form the result set of interfaces with check-box that
465                         // will be shown in the dialog for editing.
466                         Map<String, String> curResInterfaces = new HashMap<String, String>();
467                         for (Map.Entry<String, String> entry : ifTypes
468                                 .entrySet()) {
469                             if (updatedIfSet.contains(entry.getValue())) {
470                                 curResInterfaces.put(entry.getKey(),
471                                         entry.getValue());
472                             }
473                         }
474
475                         // Show the dialog for editing the resource interfaces.
476                         UpdateResourceInterfaceDialog ad = new UpdateResourceInterfaceDialog(
477                                 Display.getDefault().getActiveShell(),
478                                 curResInterfaces, ifTypes);
479                         if (ad.open() == Window.OK) {
480                             // Update the local copy of the current resource
481                             // interfaces to keep the state for save operation.
482                             updatedIfSet.clear();
483                             String newPropValue = "";
484                             for (Map.Entry<String, String> entry : curResInterfaces
485                                     .entrySet()) {
486                                 if (!newPropValue.isEmpty()) {
487                                     newPropValue += ", ";
488                                 }
489                                 String value = ifTypes.get(entry.getKey());
490                                 newPropValue += value;
491
492                                 updatedIfSet.add(value);
493                             }
494                             // Update the model
495                             MetaProperty prop = (MetaProperty) element;
496                             prop.setPropValue(newPropValue);
497                             // Update the viewer in a separate UI thread.
498                             Display.getDefault().asyncExec(new Runnable() {
499                                 @Override
500                                 public void run() {
501                                     viewer.refresh(element, true);
502                                 }
503                             });
504                         }
505                     }
506                 });
507             }
508             return editor;
509         }
510
511         @Override
512         protected Object getValue(Object element) {
513             return ((MetaProperty) element).getPropValue();
514         }
515
516         @Override
517         protected void setValue(Object element, Object value) {
518             MetaProperty prop = (MetaProperty) element;
519             if (prop.getPropName().equals(Constants.INTERFACE_TYPES)) {
520                 return;
521             }
522             prop.setPropValue(String.valueOf(value));
523             viewer.update(element, null);
524         }
525     }
526
527     private synchronized Boolean getEnableEdit() {
528         return enable_edit;
529     }
530
531     private synchronized void setEnableEdit(boolean value) {
532         enable_edit = value;
533     }
534
535     @Override
536     public void setFocus() {
537     }
538 }