Added UI Support to change resource type.
[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                     boolean result = false;
152                     Resource resourceInSelection = resourceManagerRef
153                             .getCurrentResourceInSelection();
154                     if (null != resourceInSelection) {
155
156                         // Null Check
157                         result = resourceManagerRef.isPropertyValueInvalid(
158                                 resourceInSelection, properties,
159                                 Constants.RESOURCE_URI);
160                         if (result) {
161                             MessageDialog.openError(parent.getShell(),
162                                     "Invalid Resource URI.",
163                                     Constants.INVALID_URI_MESSAGE);
164                             return;
165                         }
166
167                         result = resourceManagerRef.isPropertyValueInvalid(
168                                 resourceInSelection, properties,
169                                 Constants.RESOURCE_NAME);
170                         if (result) {
171                             MessageDialog.openError(parent.getShell(),
172                                     "Invalid Input",
173                                     "Resource Name is invalid.");
174                             return;
175                         }
176
177                         result = resourceManagerRef.isPropertyValueInvalid(
178                                 resourceInSelection, properties,
179                                 Constants.RESOURCE_TYPE);
180                         if (result) {
181                             MessageDialog.openError(parent.getShell(),
182                                     "Invalid Resource Type.",
183                                     Constants.INVALID_RESOURCE_TYPE_MESSAGE);
184                             return;
185                         }
186
187                         boolean update = false;
188                         boolean uriChange = false;
189                         boolean typeChange = false;
190                         boolean nameChange = false;
191                         boolean interfaceChange = false;
192
193                         if (resourceManagerRef.isPropValueChanged(
194                                 resourceInSelection, properties,
195                                 Constants.RESOURCE_NAME)) {
196                             update = true;
197                             nameChange = true;
198                         }
199
200                         if (resourceManagerRef.isPropValueChanged(
201                                 resourceInSelection, properties,
202                                 Constants.RESOURCE_URI)) {
203                             // Check whether the new URI is unique.
204                             if (!resourceManagerRef.isUriUnique(properties)) {
205                                 MessageDialog.openError(parent.getShell(),
206                                         "Resource URI in use",
207                                         "Resource URI is in use. Please try a different URI.");
208                                 return;
209                             }
210
211                             update = true;
212                             uriChange = true;
213                         }
214
215                         if (resourceManagerRef.isPropValueChanged(
216                                 resourceInSelection, properties,
217                                 Constants.RESOURCE_TYPE)) {
218                             update = true;
219                             typeChange = true;
220                         }
221                         // Checking whether any changes made in resource
222                         // interfaces by
223                         // comparing the current interface set and updated
224                         // interface set.
225                         if (null != updatedIfSet) {
226                             Set<String> curIfSet = resourceInSelection
227                                     .getResourceInterfaces();
228                             if (curIfSet.size() != updatedIfSet.size()) {
229                                 update = true;
230                                 interfaceChange = true;
231                             } else {
232                                 Iterator<String> itr = updatedIfSet.iterator();
233                                 while (itr.hasNext()) {
234                                     if (!curIfSet.contains(itr.next())) {
235                                         update = true;
236                                         interfaceChange = true;
237                                         break;
238                                     }
239                                 }
240                             }
241                         }
242                         if (update) {
243                             if (uriChange || typeChange || interfaceChange) {
244                                 if (resourceManagerRef
245                                         .isResourceStarted(resourceInSelection)) {
246                                     update = MessageDialog.openQuestion(
247                                             parent.getShell(),
248                                             "Save Details",
249                                             "Resource will be restarted to take the changes."
250                                                     + " Do you want to continue?");
251                                     if (!update) {
252                                         return;
253                                     }
254                                 }
255                             }
256                             try {
257                                 if (uriChange || nameChange || typeChange)
258                                     result = Activator
259                                             .getDefault()
260                                             .getResourceManager()
261                                             .updateResourceProperties(
262                                                     resourceManagerRef
263                                                             .getCurrentResourceInSelection(),
264                                                     properties, uriChange,
265                                                     nameChange, typeChange);
266                                 if (interfaceChange)
267                                     result = Activator
268                                             .getDefault()
269                                             .getResourceManager()
270                                             .updateResourceInterfaces(
271                                                     resourceInSelection,
272                                                     updatedIfSet);
273
274                             } catch (SimulatorException ex) {
275                                 result = false;
276                             }
277                             if (!result) {
278                                 MessageDialog.openInformation(
279                                         parent.getShell(), "Operation status",
280                                         "Failed to update the resource properties.");
281
282                                 // Reset the old property values.
283                                 properties = getData(resourceManagerRef
284                                         .getCurrentResourceInSelection());
285                                 updateViewer(properties);
286                             }
287                         }
288                     }
289                     cancelBtn.setEnabled(false);
290                     editBtn.setText("Edit");
291                     setEnableEdit(false);
292                 }
293             }
294         });
295
296         cancelBtn = new Button(parent, SWT.PUSH);
297         cancelBtn.setText("Cancel");
298         cancelBtn.setEnabled(false);
299         gd = new GridData();
300         gd.widthHint = 70;
301         cancelBtn.setLayoutData(gd);
302         cancelBtn.addSelectionListener(new SelectionAdapter() {
303             @Override
304             public void widgetSelected(SelectionEvent e) {
305                 Resource res = resourceManagerRef
306                         .getCurrentResourceInSelection();
307                 if (null != res) {
308                     properties = getData(res);
309                 }
310                 updateViewer(properties);
311
312                 cancelBtn.setEnabled(false);
313                 editBtn.setText("Edit");
314                 setEnableEdit(false);
315                 if (null != updatedIfSet)
316                     updatedIfSet.clear();
317             }
318         });
319
320         // Get the supported interfaces.
321         Map<String, String> ifTypesSupported = Utility
322                 .getResourceInterfaces(SingleResource.class);
323         if (null != ifTypesSupported && !ifTypesSupported.isEmpty()) {
324             ifTypes = new HashMap<String, String>();
325             String key;
326             for (Map.Entry<String, String> entry : ifTypesSupported.entrySet()) {
327                 key = entry.getValue() + " (" + entry.getKey() + ")";
328                 ifTypes.put(key, entry.getKey());
329             }
330         }
331
332         addManagerListeners();
333
334         // Check whether there is any resource selected already
335         Resource resource = resourceManagerRef.getCurrentResourceInSelection();
336         properties = getData(resource);
337         if (null != properties) {
338             updateViewer(properties);
339         }
340         updateEditControls(resource);
341     }
342
343     private void updateEditControls(Object obj) {
344         if (!editBtn.isDisposed() && !cancelBtn.isDisposed()) {
345
346             if (editBtn.getText().equals("Save")) {
347                 editBtn.setText("Edit");
348                 setEnableEdit(false);
349             }
350
351             if (null == obj) {
352                 editBtn.setEnabled(false);
353             } else {
354                 editBtn.setEnabled(true);
355             }
356             cancelBtn.setEnabled(false);
357         }
358     }
359
360     private List<MetaProperty> getData(Resource resource) {
361         if (null != resource) {
362             List<MetaProperty> metaPropertyList = resourceManagerRef
363                     .getMetaProperties(resource);
364             return metaPropertyList;
365         } else {
366             return null;
367         }
368     }
369
370     private void updateViewer(List<MetaProperty> metaPropertyList) {
371         if (null != tableViewer) {
372             Table tbl = tableViewer.getTable();
373             if (tbl.isDisposed()) {
374                 return;
375             }
376             if (null != metaPropertyList) {
377                 tableViewer.setInput(metaPropertyList.toArray());
378                 tbl.setLinesVisible(true);
379             } else {
380                 tbl.removeAll();
381                 tbl.setLinesVisible(false);
382             }
383         }
384     }
385
386     public void createColumns(final TableViewer tableViewer) {
387         TableViewerColumn propName = new TableViewerColumn(tableViewer,
388                 SWT.NONE);
389         propName.getColumn().setWidth(columnWidth[0]);
390         propName.getColumn().setText(columnHeaders[0]);
391         propName.setLabelProvider(new StyledCellLabelProvider() {
392             @Override
393             public void update(ViewerCell cell) {
394                 MetaProperty prop = (MetaProperty) cell.getElement();
395                 cell.setText(prop.getPropName());
396                 super.update(cell);
397             }
398         });
399
400         TableViewerColumn propValue = new TableViewerColumn(tableViewer,
401                 SWT.NONE);
402         propValue.getColumn().setWidth(columnWidth[1]);
403         propValue.getColumn().setText(columnHeaders[1]);
404         propValue.setLabelProvider(new StyledCellLabelProvider() {
405             @Override
406             public void update(ViewerCell cell) {
407                 MetaProperty prop = (MetaProperty) cell.getElement();
408                 cell.setText(prop.getPropValue());
409                 super.update(cell);
410             }
411         });
412         propValue.setEditingSupport(new PropValueEditor(tableViewer));
413     }
414
415     private void addManagerListeners() {
416         UiListenerHandler.getInstance().addResourceSelectionChangedUIListener(
417                 resourceSelectionChangedListener);
418     }
419
420     class PropertycontentProvider implements IStructuredContentProvider {
421
422         @Override
423         public void dispose() {
424         }
425
426         @Override
427         public void inputChanged(Viewer arg0, Object arg1, Object arg2) {
428         }
429
430         @Override
431         public Object[] getElements(Object element) {
432             return (Object[]) element;
433         }
434     }
435
436     @Override
437     public void dispose() {
438         // Unregister the listener
439         if (null != resourceSelectionChangedListener) {
440             UiListenerHandler.getInstance()
441                     .removeResourceSelectionChangedUIListener(
442                             resourceSelectionChangedListener);
443         }
444         super.dispose();
445     }
446
447     class PropValueEditor extends EditingSupport {
448
449         private final TableViewer viewer;
450
451         public PropValueEditor(TableViewer viewer) {
452             super(viewer);
453             this.viewer = viewer;
454         }
455
456         @Override
457         protected boolean canEdit(Object element) {
458             return true;
459         }
460
461         @Override
462         protected CellEditor getCellEditor(final Object element) {
463             if (!getEnableEdit()) {
464                 return null;
465             }
466             String propName = ((MetaProperty) element).getPropName();
467             CellEditor editor = new TextCellEditor(viewer.getTable());
468             if (null != propName && propName.equals(Constants.INTERFACE_TYPES)) {
469                 editor.setStyle(SWT.READ_ONLY);
470                 final Text txt = (Text) editor.getControl();
471                 txt.addModifyListener(new ModifyListener() {
472                     @Override
473                     public void modifyText(ModifyEvent e) {
474                         if (null == updatedIfSet) {
475                             return;
476                         }
477                         // Form the result set of interfaces with check-box that
478                         // will be shown in the dialog for editing.
479                         Map<String, String> curResInterfaces = new HashMap<String, String>();
480                         for (Map.Entry<String, String> entry : ifTypes
481                                 .entrySet()) {
482                             if (updatedIfSet.contains(entry.getValue())) {
483                                 curResInterfaces.put(entry.getKey(),
484                                         entry.getValue());
485                             }
486                         }
487
488                         // Show the dialog for editing the resource interfaces.
489                         UpdateResourceInterfaceDialog ad = new UpdateResourceInterfaceDialog(
490                                 Display.getDefault().getActiveShell(),
491                                 curResInterfaces, ifTypes);
492                         if (ad.open() == Window.OK) {
493                             // Update the local copy of the current resource
494                             // interfaces to keep the state for save operation.
495                             updatedIfSet.clear();
496                             String newPropValue = "";
497                             for (Map.Entry<String, String> entry : curResInterfaces
498                                     .entrySet()) {
499                                 if (!newPropValue.isEmpty()) {
500                                     newPropValue += ", ";
501                                 }
502                                 String value = ifTypes.get(entry.getKey());
503                                 newPropValue += value;
504
505                                 updatedIfSet.add(value);
506                             }
507                             // Update the model
508                             MetaProperty prop = (MetaProperty) element;
509                             prop.setPropValue(newPropValue);
510                             // Update the viewer in a separate UI thread.
511                             Display.getDefault().asyncExec(new Runnable() {
512                                 @Override
513                                 public void run() {
514                                     viewer.refresh(element, true);
515                                 }
516                             });
517                         }
518                     }
519                 });
520             }
521             return editor;
522         }
523
524         @Override
525         protected Object getValue(Object element) {
526             return ((MetaProperty) element).getPropValue();
527         }
528
529         @Override
530         protected void setValue(Object element, Object value) {
531             MetaProperty prop = (MetaProperty) element;
532             if (prop.getPropName().equals(Constants.INTERFACE_TYPES)) {
533                 return;
534             }
535             prop.setPropValue(String.valueOf(value));
536             viewer.update(element, null);
537         }
538     }
539
540     private synchronized Boolean getEnableEdit() {
541         return enable_edit;
542     }
543
544     private synchronized void setEnableEdit(boolean value) {
545         enable_edit = value;
546     }
547
548     @Override
549     public void setFocus() {
550     }
551 }