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