]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/componentTypeEditor/ConfigurationPropertiesSection.java
Support for creating shared ontology dump to git
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / componentTypeEditor / ConfigurationPropertiesSection.java
1 package org.simantics.modeling.ui.componentTypeEditor;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.Collections;
6 import java.util.HashMap;
7 import java.util.HashSet;
8 import java.util.List;
9 import java.util.Map;
10 import java.util.Set;
11
12 import org.eclipse.jface.dialogs.IDialogSettings;
13 import org.eclipse.jface.layout.GridDataFactory;
14 import org.eclipse.jface.layout.GridLayoutFactory;
15 import org.eclipse.jface.layout.TableColumnLayout;
16 import org.eclipse.jface.resource.ImageDescriptor;
17 import org.eclipse.jface.viewers.ColumnWeightData;
18 import org.eclipse.jface.window.Window;
19 import org.eclipse.swt.SWT;
20 import org.eclipse.swt.custom.TableEditor;
21 import org.eclipse.swt.events.DisposeEvent;
22 import org.eclipse.swt.events.DisposeListener;
23 import org.eclipse.swt.events.MouseAdapter;
24 import org.eclipse.swt.events.MouseEvent;
25 import org.eclipse.swt.events.SelectionAdapter;
26 import org.eclipse.swt.events.SelectionEvent;
27 import org.eclipse.swt.graphics.Color;
28 import org.eclipse.swt.graphics.Rectangle;
29 import org.eclipse.swt.layout.FillLayout;
30 import org.eclipse.swt.widgets.Button;
31 import org.eclipse.swt.widgets.Composite;
32 import org.eclipse.swt.widgets.Control;
33 import org.eclipse.swt.widgets.Shell;
34 import org.eclipse.swt.widgets.Table;
35 import org.eclipse.swt.widgets.TableColumn;
36 import org.eclipse.swt.widgets.TableItem;
37 import org.eclipse.ui.PlatformUI;
38 import org.eclipse.ui.forms.widgets.Form;
39 import org.eclipse.ui.forms.widgets.FormToolkit;
40 import org.eclipse.ui.forms.widgets.Section;
41 import org.simantics.Simantics;
42 import org.simantics.databoard.Bindings;
43 import org.simantics.db.ReadGraph;
44 import org.simantics.db.Resource;
45 import org.simantics.db.WriteGraph;
46 import org.simantics.db.common.CommentMetadata;
47 import org.simantics.db.common.request.ObjectsWithType;
48 import org.simantics.db.common.request.PossibleIndexRoot;
49 import org.simantics.db.common.request.UniqueRead;
50 import org.simantics.db.common.request.WriteRequest;
51 import org.simantics.db.common.utils.NameUtils;
52 import org.simantics.db.exception.DatabaseException;
53 import org.simantics.db.layer0.adapter.CopyHandler2;
54 import org.simantics.db.layer0.adapter.Instances;
55 import org.simantics.db.layer0.util.Layer0Utils;
56 import org.simantics.db.layer0.variable.Variable;
57 import org.simantics.db.layer0.variable.Variables;
58 import org.simantics.layer0.Layer0;
59 import org.simantics.modeling.ui.Activator;
60 import org.simantics.modeling.ui.componentTypeEditor.LiftPropertiesDialog.LiftedProperty;
61 import org.simantics.modeling.userComponent.ComponentTypeCommands;
62 import org.simantics.modeling.utils.ComponentTypePropertiesResult;
63 import org.simantics.modeling.utils.ComponentTypeViewerPropertyInfo;
64 import org.simantics.selectionview.SelectionViewResources;
65 import org.simantics.structural.stubs.StructuralResource2;
66 import org.simantics.utils.datastructures.Pair;
67 import org.slf4j.Logger;
68 import org.slf4j.LoggerFactory;
69
70 public class ConfigurationPropertiesSection implements ComponentTypeViewerSection {
71
72     private static final Logger LOGGER = LoggerFactory.getLogger(ConfigurationPropertiesSection.class);
73
74     private static final String[] COLUMN_NAMES = {
75             Messages.ConfigurationPropertiesSection_Name,
76             Messages.ConfigurationPropertiesSection_Type,
77             Messages.ConfigurationPropertiesSection_DefaultValue,
78             Messages.ConfigurationPropertiesSection_Unit,
79             Messages.ConfigurationPropertiesSection_Range,
80             Messages.ConfigurationPropertiesSection_Label,
81             Messages.ConfigurationPropertiesSection_Description
82     };
83     private static final int[] COLUMN_LENGTHS =
84             new int[] { 120, 100, 100, 50, 100, 100, 100 };
85     private static final int[] COLUMN_WEIGHTS =
86             new int[] { 0, 0, 0, 0, 0, 50, 100 };
87
88     /**
89      * Configuration property table column indexes that are to be considered
90      * immutable when the property relation is immutable. Note that relation
91      * immutability does not make the asserted default value immutable.
92      */
93     private static final int[] IMMUTABLE_COLUMNS_WITH_IMMUTABLE_RELATION =
94         { 0, 1, 3, 4, 5, 6 };
95     ComponentTypeViewerData data;
96     
97     Table table;
98     TableColumn[] columns;
99     TableEditor editor;
100     Button newProperty;
101     Button removeProperty;
102     Button liftProperties;
103
104     boolean hasTypes = false;
105     Button setTypes;
106     
107     Section section;
108     
109     public ConfigurationPropertiesSection(ComponentTypeViewerData data) {
110         this.data = data;
111         FormToolkit tk = data.tk;
112         Form form = data.form;
113         
114         section = tk.createSection(form.getBody(), Section.TITLE_BAR | Section.EXPANDED);
115         section.setLayout(new FillLayout());
116         section.setText(Messages.ConfigurationPropertiesSection_ConfigurationProperties);
117
118         Composite sectionBody = tk.createComposite(section);
119         GridLayoutFactory.fillDefaults().numColumns(2).applyTo(sectionBody);
120         section.setClient(sectionBody);
121
122         Composite tableComposite = tk.createComposite(sectionBody);
123         GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(tableComposite);
124         TableColumnLayout tcl = new TableColumnLayout();
125         tableComposite.setLayout(tcl);
126
127         table = tk.createTable(tableComposite, SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER);
128         table.setLinesVisible(true);
129         table.setHeaderVisible(true);
130
131         columns = new TableColumn[COLUMN_NAMES.length];
132         for(int i=0;i<COLUMN_NAMES.length;++i) {
133             TableColumn column = new TableColumn(table, SWT.NONE);
134             columns[i] = column;
135             tcl.setColumnData(column, new ColumnWeightData(COLUMN_WEIGHTS[i], COLUMN_LENGTHS[i], true));
136             column.setText(COLUMN_NAMES[i]);
137         }
138
139         // Table editor
140         editor = new TableEditor(table);
141         editor.grabHorizontal = true;
142         editor.grabVertical = true;
143         editor.horizontalAlignment = SWT.LEFT;
144         table.addMouseListener(new MouseAdapter() {
145             @Override
146             public void mouseDown(MouseEvent e) {
147                 // Clean up any previous editor control
148                 Control oldEditor = editor.getEditor();
149                 if (oldEditor != null) oldEditor.dispose();
150
151                 if (data.readOnly)
152                     return;
153
154                 // Relative position
155                 Rectangle tableBounds = table.getClientArea();
156                 int rx = e.x - tableBounds.x;
157                 int ry = e.y - tableBounds.y;
158
159                 // Find cell
160                 TableItem selectedItem = null;
161                 int selectedColumn = -1;
162                 Rectangle selectedItemBounds = null;
163                 for(TableItem item : table.getItems()) {
164                     for(int column = 0;column < COLUMN_NAMES.length;++column) {
165                         Rectangle bounds = item.getBounds(column);
166                         if(bounds.contains(rx, ry)) {
167                             selectedItemBounds = bounds;
168                             selectedItem = item;
169                             selectedColumn = column;
170                             break;
171                         }
172                     }
173                 }
174                 if(selectedItem == null) {
175                     return;
176                 }
177
178                 // Table editor
179                 final int column = selectedColumn; 
180                 final ComponentTypeViewerPropertyInfo propertyInfo = (ComponentTypeViewerPropertyInfo)selectedItem.getData();
181                 final Resource resource = propertyInfo.resource;
182                 switch (column) {
183                 case 0:
184                     data.editName(table, editor, propertyInfo, selectedItem, column, ComponentTypeViewerData.PROPERTY_NAME_PATTERN);
185                     break;
186
187                 case 1:
188                     data.editType(table, editor, propertyInfo, selectedItem, column, selectedItem.getText(4), true);
189                     break;
190
191                 case 2: {
192                     data.editValue(table, editor, propertyInfo, selectedItem, column, data.readOnly ? null : new StringWriter() {
193                         @Override
194                         public void perform(WriteGraph graph, String newValue) throws DatabaseException {
195                             graph.markUndoPoint();
196                             ComponentTypeCommands.setDefaultValue(graph, data.componentType, propertyInfo.resource, newValue);
197                         }
198                     }, null);
199                 } break;
200
201                 case 3:
202                     data.editUnit(table, editor, propertyInfo, selectedItem, column);
203                     break;
204
205                 case 4:
206                     data.editRange(table, editor, propertyInfo, selectedItem, selectedItemBounds, column);
207                     break;
208
209                 case 5:
210                     data.editValue(table, editor, propertyInfo, selectedItem, column, propertyInfo.immutable ? null : new StringWriter() {
211                         @Override
212                         public void perform(WriteGraph graph, String newValue) throws DatabaseException {
213                             graph.markUndoPoint();
214                             String value = newValue.isEmpty() ? null : newValue;
215                             ComponentTypeCommands.setLabel(graph, resource, value);
216                         }
217                     }, null);
218                     break;
219
220                 case 6:
221                     data.editMultilineText(table, editor, propertyInfo, selectedItem, selectedItemBounds, column, new StringWriter() {
222                         @Override
223                         public void perform(WriteGraph graph, String newValue) throws DatabaseException {
224                             graph.markUndoPoint();
225                             String value = newValue.isEmpty() ? null : newValue;
226                             ComponentTypeCommands.setDescription(graph, resource, value);
227                         }
228                     });
229                     break;
230                 }
231             }
232         });
233
234         // Buttons
235
236         Composite buttons = tk.createComposite(sectionBody);
237         GridDataFactory.fillDefaults().applyTo(buttons);
238         GridLayoutFactory.fillDefaults().applyTo(buttons);
239
240         newProperty = tk.createButton(buttons, Messages.ConfigurationPropertiesSection_NewProperty, SWT.PUSH);
241         GridDataFactory.fillDefaults().applyTo(newProperty);
242         removeProperty = tk.createButton(buttons, Messages.ConfigurationPropertiesSection_RemoveProperty, SWT.PUSH);
243         GridDataFactory.fillDefaults().applyTo(removeProperty);
244
245         liftProperties = tk.createButton(buttons, Messages.ConfigurationPropertiesSection_LiftProperties, SWT.PUSH);
246         GridDataFactory.fillDefaults().applyTo(liftProperties);
247
248         hasTypes = !getTypes().isEmpty();
249         
250         if(hasTypes) {
251             setTypes = tk.createButton(buttons, Messages.ConfigurationPropertiesSection_AssignTypes, SWT.PUSH);
252             GridDataFactory.fillDefaults().applyTo(setTypes);
253         }
254
255         // Actions
256
257         table.addSelectionListener(new SelectionAdapter() {
258             @Override
259             public void widgetSelected(SelectionEvent e) {
260                 TableItem[] sel = table.getSelection();
261                 for (TableItem item : sel) {
262                     ComponentTypeViewerPropertyInfo pi = (ComponentTypeViewerPropertyInfo) item.getData();
263                     if (pi.immutable) {
264                         removeProperty.setEnabled(false);
265                         return;
266                     }
267                 }
268                 removeProperty.setEnabled(true);
269             }
270         });
271
272         newProperty.addSelectionListener(new SelectionAdapter() {
273             @Override
274             public void widgetSelected(SelectionEvent e) {
275                 if(editor.getEditor() != null)
276                     editor.getEditor().dispose();
277                 Simantics.getSession().async(new WriteRequest() {
278                     @Override
279                     public void perform(WriteGraph graph)
280                             throws DatabaseException {
281                         ComponentTypeCommands.createPropertyWithDefaults(graph, data.componentType);
282                     }
283                 });
284             }
285         });
286
287         removeProperty.addSelectionListener(new SelectionAdapter() {
288             @Override
289             public void widgetSelected(SelectionEvent e) {
290                 if(editor.getEditor() != null)
291                     editor.getEditor().dispose();
292                 final List<Resource> propertiesToBeRemoved = 
293                         new ArrayList<>();
294                 for(TableItem item : table.getSelection()) {
295                     ComponentTypeViewerPropertyInfo info = (ComponentTypeViewerPropertyInfo) item.getData();
296                     if (!info.immutable)
297                         propertiesToBeRemoved.add(info.resource);
298                 }
299                 //System.out.println("remove " + propertiesToBeRemoved.size() + " resources"); //$NON-NLS-1$ //$NON-NLS-2$
300                 if(!propertiesToBeRemoved.isEmpty())
301                     Simantics.getSession().async(new WriteRequest() {
302                         @Override
303                         public void perform(WriteGraph graph)
304                                 throws DatabaseException {
305                             graph.markUndoPoint();
306                             for(Resource property : propertiesToBeRemoved)
307                                 ComponentTypeCommands.removeProperty(graph, data.componentType, property);
308                         }
309                     });
310             }
311         });
312         
313         liftProperties.addSelectionListener(new SelectionAdapter() {
314             @Override
315             public void widgetSelected(SelectionEvent e) {
316                 
317                 if(editor.getEditor() != null)
318                     editor.getEditor().dispose();
319
320                 try {
321                 
322                     Map<LiftedProperty, Pair<String, ImageDescriptor>> map = Simantics.sync(new UniqueRead<Map<LiftedProperty,Pair<String,ImageDescriptor>>>() {
323     
324                         @Override
325                         public Map<LiftedProperty, Pair<String, ImageDescriptor>> perform(ReadGraph graph) throws DatabaseException {
326                             
327                             Map<LiftedProperty, Pair<String,ImageDescriptor>> map = new HashMap<>(); 
328                             
329                             Layer0 L0 = Layer0.getInstance(graph);
330                             StructuralResource2 STR = StructuralResource2.getInstance(graph);
331                             SelectionViewResources SEL = SelectionViewResources.getInstance(graph);
332     
333                             Resource composite = graph.getPossibleObject(data.componentType, STR.IsDefinedBy);
334                             if(composite == null) return map;
335
336
337                             Set<String> existing = new HashSet<>();
338                             for(Resource predicate : graph.getObjects(data.componentType, L0.DomainOf)) {
339                                 if(graph.isSubrelationOf(predicate, L0.HasProperty)) {
340                                     existing.add(NameUtils.getSafeName(graph, predicate));
341                                 }
342                             }
343                             
344                             for(Resource component : graph.syncRequest(new ObjectsWithType(composite, L0.ConsistsOf, STR.Component))) {
345     
346                                 Resource type = graph.getPossibleType(component, STR.Component);
347                                 if(type == null) continue;
348                                 
349                                 String componentName = NameUtils.getSafeName(graph, component);
350     
351                                 for(Resource predicate : graph.getPredicates(component)) {
352                                     if(graph.isSubrelationOf(predicate, L0.HasProperty)) {
353     
354                                         // Do not list properties shown under other properties
355                                         if(graph.hasStatement(predicate, SEL.IsShownUnder)) continue;
356                                         
357                                         // Do not list properties that are not visible in selection view
358                                         if(!graph.hasStatement(predicate, SEL.HasStandardPropertyInfo)) continue;
359                                         
360                                         // Some properties are explicitly marked as non-liftable
361                                         Boolean canBeLifted = graph.getPossibleRelatedValue(predicate, SEL.canBeLifted, Bindings.BOOLEAN);
362                                         if(canBeLifted != null && !canBeLifted) continue;
363                                         
364                                         String predicateName = NameUtils.getSafeName(graph, predicate);
365                                         if(existing.contains(predicateName)) continue;
366                                         
367                                         String name = componentName + " " + predicateName; //$NON-NLS-1$
368                                         map.put(new LiftedProperty(component, type, predicate), new Pair<String, ImageDescriptor>(name, null));
369                                         
370                                     }
371                                 }
372                                 
373                             }
374                             
375                             return map;
376                             
377                         }
378     
379                     });
380                     
381                     Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
382                     LiftPropertiesDialog dialog = new LiftPropertiesDialog(shell, map, Messages.ConfigurationPropertiesSection_SelectPropertiesToLift) {
383                         @Override
384                         protected IDialogSettings getBaseDialogSettings() {
385                             return Activator.getDefault().getDialogSettings();
386                         }
387                     };
388                     if (dialog.open() == Window.OK) {
389                         final Collection<LiftedProperty> _result = dialog.getResultT();
390                         final boolean mapProperties = dialog.getMapProperties();
391                         if (!_result.isEmpty()) {
392                             Simantics.getSession().async(new WriteRequest() {
393                                 public Resource findAssertion(ReadGraph graph, Resource sourceType, Resource predicate) throws DatabaseException {
394                                     Collection<Resource> ass = graph.getAssertedObjects(sourceType, predicate);
395                                     if(ass.size() == 1) return ass.iterator().next();
396                                     return null;
397                                 }
398                                 
399                                 public void processSubs(ReadGraph graph, Resource predicate, Resource component, Resource componentType, List<LiftedProperty> result, List<Resource> properties, List<Resource> assertions) throws DatabaseException {
400                                     SelectionViewResources SEL = SelectionViewResources.getInstance(graph);
401                                     for(Resource sub : graph.getObjects(predicate, SEL.UnderOf)) {
402                                         Resource ass = findAssertion(graph, componentType, sub);
403                                         if(ass == null) continue;
404                                         result.add(new LiftedProperty(component, componentType, sub));
405                                         properties.add(sub);
406                                         assertions.add(ass);
407                                         processSubs(graph, sub, component, componentType, result, properties, assertions);
408                                     }
409                                 }
410                                 
411                                 @Override
412                                 public void perform(WriteGraph graph) throws DatabaseException {
413                                     
414                                     Layer0 L0 = Layer0.getInstance(graph);
415                                     graph.markUndoPoint();
416                                     List<Resource> properties = new ArrayList<>();
417                                     List<Resource> assertions = new ArrayList<>();
418                                     
419                                     List<LiftedProperty> result = new ArrayList<>(); 
420                                     for(LiftedProperty p : _result) {
421                                         Resource ass = findAssertion(graph, p.getComponentType(), p.getPredicate());
422                                         if(ass == null) continue;
423                                         result.add(p);
424                                         properties.add(p.getPredicate());
425                                         assertions.add(ass);
426                                         processSubs(graph, p.getPredicate(), p.getComponent(), p.getComponentType(), result, properties, assertions);
427                                     }
428                                     
429                                     CopyHandler2 ch = Layer0Utils.getPossibleCopyHandler(graph, properties);
430                                     Collection<Resource> copies = Layer0Utils.copyTo(graph, data.componentType, null, ch, null);
431                                     int index = 0;
432                                     for(Resource copy : copies) {
433                                         Resource ass = assertions.get(index);
434                                         LiftedProperty p = result.get(index);
435                                         Collection<Resource> copyAss = Layer0Utils.copyTo(graph, null, ass);
436                                         if(copyAss.size() == 1) {
437                                             graph.deny(copy, L0.HasDomain);
438                                             graph.claim(data.componentType, L0.DomainOf, copy);
439                                             Layer0Utils.assert_(graph, data.componentType, copy, copyAss.iterator().next());
440                                             CommentMetadata cm = graph.getMetadata(CommentMetadata.class);
441                                             graph.addMetadata(cm.add("Lifted property " + NameUtils.getSafeName(graph, copy) + " into "+ NameUtils.getSafeName(graph, data.componentType))); //$NON-NLS-1$ //$NON-NLS-2$
442                                         }
443                                         if(mapProperties) {
444                                             Variable v = Variables.getVariable(graph, p.getComponent());
445                                             Variable property = v.getProperty(graph, p.getPredicate());
446                                             Variable displayValue = property.getProperty(graph, Variables.DISPLAY_VALUE);
447                                             displayValue.setValue(graph, "=" + NameUtils.getSafeName(graph, p.getPredicate()), Bindings.STRING); //$NON-NLS-1$
448                                         }
449                                         index++;
450                                     }
451                                     
452                                 }
453                             });
454                         }
455                     }
456
457                 } catch (DatabaseException e1) {
458                     
459                     LOGGER.error("Lifting properties failed", e1); //$NON-NLS-1$
460                     return;
461                     
462                 }
463                 
464             }
465         });
466
467         if(hasTypes) {
468             
469             setTypes.addSelectionListener(new SelectionAdapter() {
470                 @Override
471                 public void widgetSelected(SelectionEvent e) {
472                     if(editor.getEditor() != null)
473                         editor.getEditor().dispose();
474                     final List<Resource> propertiesToSet = 
475                             new ArrayList<>();
476                     for(TableItem item : table.getSelection())
477                         propertiesToSet.add(((ComponentTypeViewerPropertyInfo)item.getData()).resource);
478                     
479                     if(propertiesToSet.size() != 1) return;
480
481                     Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
482                     SetTypesDialog page = new SetTypesDialog(shell, getTypes(), Messages.ConfigurationPropertiesSection_SelectUserTypesForProp);
483                     if (page.open() == Window.OK) {
484                         final Object[] result = page.getResult();
485                         if (result != null && result.length > 0) {
486                             Simantics.getSession().async(new WriteRequest() {
487                                 @Override
488                                 public void perform(WriteGraph graph)
489                                         throws DatabaseException {
490                                     for(Object type : result) {
491                                         Layer0 L0 = Layer0.getInstance(graph);
492                                         graph.claim(propertiesToSet.get(0), L0.InstanceOf, null, (Resource)type);
493                                     }
494                                 }
495                             });
496                         }
497                     }
498                     
499                 }
500             });
501             
502         }
503
504         table.addDisposeListener(new DisposeListener() {
505             @Override
506             public void widgetDisposed(DisposeEvent e) {
507                 tk.dispose();
508             }
509         });
510     }
511
512     public void update(ComponentTypePropertiesResult result) {
513         if (table.isDisposed())
514             return;
515         
516         // Save old selection
517         Set<ComponentTypeViewerPropertyInfo> selected = new HashSet<>();
518         List<TableItem> selectedItems = new ArrayList<>(selected.size());
519         for (int i : table.getSelectionIndices()) {
520             TableItem item = table.getItem(i);
521             selected.add((ComponentTypeViewerPropertyInfo) item.getData());
522         }
523
524         int topIndex = table.getTopIndex();
525
526         table.removeAll();
527
528         if(editor.getEditor() != null)
529             editor.getEditor().dispose();
530
531         for(ComponentTypeViewerPropertyInfo info : result.getProperties()) {
532             boolean immutable = result.isImmutable() || info.immutable;
533             Color fg = immutable ? table.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY) : null;
534             if(info.sectionSpecificData != null)
535                 continue;
536
537             TableItem item = new TableItem(table, SWT.NONE);
538
539             item.setText(0, info.name);
540             item.setText(1, info.type);
541             item.setText(2, info.defaultValue);
542             item.setText(3, info.unitString());
543             item.setText(4, info.rangeString());
544             item.setText(5, info.label);
545             item.setText(6, info.description);
546
547             for (int columnIndex : IMMUTABLE_COLUMNS_WITH_IMMUTABLE_RELATION)
548                 item.setForeground(columnIndex, fg);
549
550             item.setData(info);
551
552             if (selected.contains(info))
553                 selectedItems.add(item);
554         }
555
556         // Restore old selection
557         table.setTopIndex(topIndex);
558         table.setSelection(selectedItems.toArray(new TableItem[selectedItems.size()]));
559         table.redraw();
560     }
561     
562     private Map<Resource, Pair<String, ImageDescriptor>> getTypes() {
563         try {
564             return Simantics.getSession().syncRequest(new UniqueRead<Map<Resource, Pair<String, ImageDescriptor>>>() {
565                 @Override
566                 public Map<Resource, Pair<String, ImageDescriptor>> perform(ReadGraph graph)
567                         throws DatabaseException {
568                     StructuralResource2 STR = StructuralResource2.getInstance(graph);
569                     Resource indexRoot = graph.syncRequest(new PossibleIndexRoot(data.componentType));
570                     Instances query = graph.adapt(STR.UserDefinedProperty, Instances.class);
571                     Collection<Resource> types = query.find(graph, indexRoot);
572                     Map<Resource, Pair<String, ImageDescriptor>> result = new HashMap<>();
573                     for(Resource type : types) {
574                         String name = NameUtils.getSafeLabel(graph, type);
575                         result.put(type, new Pair<String, ImageDescriptor>(name, null));
576                     }
577                     return result;
578                 }
579             });
580         } catch (DatabaseException e) {
581             LOGGER.error("Finding UserDefinedProperties failed.", e); //$NON-NLS-1$
582             return Collections.emptyMap();
583         }
584     }
585
586     @Override
587     public void setReadOnly(boolean readOnly) {
588         boolean e = !readOnly;
589         newProperty.setEnabled(e);
590         removeProperty.setEnabled(e);
591         liftProperties.setEnabled(e);
592     }
593     
594     @Override
595     public Section getSection() {
596         return section;
597     }
598
599     @Override
600     public double getPriority() {
601         return 0;
602     }
603
604     @Override
605     public Object getSectionSpecificData(ReadGraph graph,
606             ComponentTypeViewerPropertyInfo info) throws DatabaseException {
607         return null;
608     }
609
610     @Override
611     public double getDataPriority() {
612         return 0.0;
613     }
614 }