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