d5fd2d67a585ffafa8797848f5db7f77be73259a
[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                         if (null != curIfSet && null != updatedIfSet) {
227                             if (curIfSet.size() != updatedIfSet.size()) {
228                                 update = true;
229                                 interfaceChange = true;
230                             } else {
231                                 Iterator<String> itr = updatedIfSet.iterator();
232                                 while (itr.hasNext()) {
233                                     if (!curIfSet.contains(itr.next())) {
234                                         update = true;
235                                         interfaceChange = true;
236                                         break;
237                                     }
238                                 }
239                             }
240                         }
241                         if (update) {
242                             if (uriChange || typeChange || interfaceChange) {
243                                 if (resourceManagerRef
244                                         .isResourceStarted(resourceInSelection)) {
245                                     update = MessageDialog.openQuestion(
246                                             parent.getShell(),
247                                             "Save Details",
248                                             "Resource will be restarted to take the changes."
249                                                     + " Do you want to continue?");
250                                     if (!update) {
251                                         return;
252                                     }
253                                 }
254                             }
255                             try {
256                                 if (uriChange || nameChange || typeChange)
257                                     result = Activator
258                                             .getDefault()
259                                             .getResourceManager()
260                                             .updateResourceProperties(
261                                                     resourceManagerRef
262                                                             .getCurrentResourceInSelection(),
263                                                     properties, uriChange,
264                                                     nameChange, typeChange);
265                                 if (interfaceChange)
266                                     result = Activator
267                                             .getDefault()
268                                             .getResourceManager()
269                                             .updateResourceInterfaces(
270                                                     resourceInSelection,
271                                                     updatedIfSet);
272
273                             } catch (SimulatorException ex) {
274                                 result = false;
275                             }
276                             if (!result) {
277                                 MessageDialog.openInformation(
278                                         parent.getShell(), "Operation status",
279                                         "Failed to update the resource properties.");
280
281                                 // Reset the old property values.
282                                 properties = getData(resourceManagerRef
283                                         .getCurrentResourceInSelection());
284                                 updateViewer(properties);
285                             }
286                         }
287                     }
288                     cancelBtn.setEnabled(false);
289                     editBtn.setText("Edit");
290                     setEnableEdit(false);
291                 }
292             }
293         });
294
295         cancelBtn = new Button(parent, SWT.PUSH);
296         cancelBtn.setText("Cancel");
297         cancelBtn.setEnabled(false);
298         gd = new GridData();
299         gd.widthHint = 70;
300         cancelBtn.setLayoutData(gd);
301         cancelBtn.addSelectionListener(new SelectionAdapter() {
302             @Override
303             public void widgetSelected(SelectionEvent e) {
304                 Resource res = resourceManagerRef
305                         .getCurrentResourceInSelection();
306                 if (null != res) {
307                     properties = getData(res);
308                 }
309                 updateViewer(properties);
310
311                 cancelBtn.setEnabled(false);
312                 editBtn.setText("Edit");
313                 setEnableEdit(false);
314                 if (null != updatedIfSet)
315                     updatedIfSet.clear();
316             }
317         });
318
319         // Get the supported interfaces.
320         Map<String, String> ifTypesSupported = Utility
321                 .getResourceInterfaces(SingleResource.class);
322         if (null != ifTypesSupported && !ifTypesSupported.isEmpty()) {
323             ifTypes = new HashMap<String, String>();
324             String key;
325             for (Map.Entry<String, String> entry : ifTypesSupported.entrySet()) {
326                 key = entry.getValue() + " (" + entry.getKey() + ")";
327                 ifTypes.put(key, entry.getKey());
328             }
329         }
330
331         addManagerListeners();
332
333         // Check whether there is any resource selected already
334         Resource resource = resourceManagerRef.getCurrentResourceInSelection();
335         properties = getData(resource);
336         if (null != properties) {
337             updateViewer(properties);
338         }
339         updateEditControls(resource);
340     }
341
342     private void updateEditControls(Object obj) {
343         if (!editBtn.isDisposed() && !cancelBtn.isDisposed()) {
344
345             if (editBtn.getText().equals("Save")) {
346                 editBtn.setText("Edit");
347                 setEnableEdit(false);
348             }
349
350             if (null == obj) {
351                 editBtn.setEnabled(false);
352             } else {
353                 editBtn.setEnabled(true);
354             }
355             cancelBtn.setEnabled(false);
356         }
357     }
358
359     private List<MetaProperty> getData(Resource resource) {
360         if (null != resource) {
361             List<MetaProperty> metaPropertyList = resourceManagerRef
362                     .getMetaProperties(resource);
363             return metaPropertyList;
364         } else {
365             return null;
366         }
367     }
368
369     private void updateViewer(List<MetaProperty> metaPropertyList) {
370         if (null != tableViewer) {
371             Table tbl = tableViewer.getTable();
372             if (tbl.isDisposed()) {
373                 return;
374             }
375             if (null != metaPropertyList) {
376                 tableViewer.setInput(metaPropertyList.toArray());
377                 tbl.setLinesVisible(true);
378             } else {
379                 tbl.removeAll();
380                 tbl.setLinesVisible(false);
381             }
382         }
383     }
384
385     public void createColumns(final TableViewer tableViewer) {
386         TableViewerColumn propName = new TableViewerColumn(tableViewer,
387                 SWT.NONE);
388         propName.getColumn().setWidth(columnWidth[0]);
389         propName.getColumn().setText(columnHeaders[0]);
390         propName.setLabelProvider(new StyledCellLabelProvider() {
391             @Override
392             public void update(ViewerCell cell) {
393                 MetaProperty prop = (MetaProperty) cell.getElement();
394                 cell.setText(prop.getPropName());
395                 super.update(cell);
396             }
397         });
398
399         TableViewerColumn propValue = new TableViewerColumn(tableViewer,
400                 SWT.NONE);
401         propValue.getColumn().setWidth(columnWidth[1]);
402         propValue.getColumn().setText(columnHeaders[1]);
403         propValue.setLabelProvider(new StyledCellLabelProvider() {
404             @Override
405             public void update(ViewerCell cell) {
406                 MetaProperty prop = (MetaProperty) cell.getElement();
407                 cell.setText(prop.getPropValue());
408                 super.update(cell);
409             }
410         });
411         propValue.setEditingSupport(new PropValueEditor(tableViewer));
412     }
413
414     private void addManagerListeners() {
415         UiListenerHandler.getInstance().addResourceSelectionChangedUIListener(
416                 resourceSelectionChangedListener);
417     }
418
419     private static class PropertycontentProvider implements
420             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                             StringBuilder newPropValue = new StringBuilder();
497                             for (Map.Entry<String, String> entry : curResInterfaces
498                                     .entrySet()) {
499                                 if (!newPropValue.toString().isEmpty()) {
500                                     newPropValue.append(", ");
501                                 }
502                                 String value = ifTypes.get(entry.getKey());
503                                 newPropValue.append(value);
504
505                                 updatedIfSet.add(value);
506                             }
507                             // Update the model
508                             MetaProperty prop = (MetaProperty) element;
509                             prop.setPropValue(newPropValue.toString());
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 }