]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/componentTypeEditor/ComponentTypeViewer.java
Sync git svn branch with SVN repository r33153.
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / componentTypeEditor / ComponentTypeViewer.java
1 /*******************************************************************************\r
2  * Copyright (c) 2012 Association for Decentralized Information Management in\r
3  * Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.modeling.ui.componentTypeEditor;\r
13 \r
14 import java.util.ArrayList;\r
15 import java.util.Collections;\r
16 import java.util.List;\r
17 \r
18 import org.eclipse.jface.dialogs.IMessageProvider;\r
19 import org.eclipse.jface.resource.JFaceResources;\r
20 import org.eclipse.jface.resource.LocalResourceManager;\r
21 import org.eclipse.jface.resource.ResourceManager;\r
22 import org.eclipse.swt.SWT;\r
23 import org.eclipse.swt.events.SelectionAdapter;\r
24 import org.eclipse.swt.events.SelectionEvent;\r
25 import org.eclipse.swt.layout.FormAttachment;\r
26 import org.eclipse.swt.layout.FormData;\r
27 import org.eclipse.swt.layout.FormLayout;\r
28 import org.eclipse.swt.widgets.Composite;\r
29 import org.eclipse.swt.widgets.Sash;\r
30 import org.eclipse.ui.forms.IMessageManager;\r
31 import org.eclipse.ui.forms.widgets.Form;\r
32 import org.eclipse.ui.forms.widgets.FormToolkit;\r
33 import org.osgi.framework.BundleContext;\r
34 import org.osgi.framework.InvalidSyntaxException;\r
35 import org.osgi.framework.ServiceReference;\r
36 import org.simantics.Simantics;\r
37 import org.simantics.databoard.Bindings;\r
38 import org.simantics.databoard.binding.Binding;\r
39 import org.simantics.databoard.binding.error.BindingException;\r
40 import org.simantics.databoard.type.Datatype;\r
41 import org.simantics.databoard.type.NumberType;\r
42 import org.simantics.db.ReadGraph;\r
43 import org.simantics.db.Resource;\r
44 import org.simantics.db.common.NamedResource;\r
45 import org.simantics.db.common.request.UniqueRead;\r
46 import org.simantics.db.common.utils.NameUtils;\r
47 import org.simantics.db.exception.DatabaseException;\r
48 import org.simantics.db.layer0.util.Layer0Utils;\r
49 import org.simantics.db.procedure.Listener;\r
50 import org.simantics.db.request.Read;\r
51 import org.simantics.layer0.Layer0;\r
52 import org.simantics.modeling.ui.Activator;\r
53 import org.simantics.operation.Layer0X;\r
54 import org.simantics.structural.stubs.StructuralResource2;\r
55 import org.simantics.utils.ui.ErrorLogger;\r
56 import org.simantics.utils.ui.SWTUtils;\r
57 \r
58 public class ComponentTypeViewer {\r
59 \r
60     ComponentTypeViewerData data;\r
61     \r
62     ResourceManager resourceManager;\r
63     \r
64     ArrayList<ComponentTypeViewerSection> sections = new ArrayList<ComponentTypeViewerSection>(3);\r
65 \r
66     public ComponentTypeViewer(Composite parent, Resource _componentType, String formTitle) {\r
67         // Form\r
68         FormToolkit tk = new FormToolkit(parent.getDisplay());\r
69         Form form = tk.createForm(parent);\r
70         tk.decorateFormHeading(form);\r
71         resourceManager = new LocalResourceManager(JFaceResources.getResources(), form);\r
72         form.setText(formTitle);\r
73         form.setImage(resourceManager.createImage(Activator.COMPONENT_TYPE_ICON));\r
74         {\r
75             FormLayout layout = new FormLayout();\r
76             layout.marginBottom = 10;\r
77             layout.marginTop = 10;\r
78             layout.marginLeft = 10;\r
79             layout.marginRight = 10;\r
80             form.getBody().setLayout(layout);\r
81         }\r
82         \r
83         // Data\r
84         data = new ComponentTypeViewerData(tk, _componentType, form);\r
85 \r
86         // Sections\r
87         \r
88         sections.add(new ConfigurationPropertiesSection(data));\r
89         sections.add(new DerivedPropertiesSection(data));\r
90 \r
91         BundleContext bundleContext = Activator.getContext();\r
92         try {\r
93             ArrayList<ComponentTypeViewerSectionFactory> factories = \r
94                     Simantics.getSession().syncRequest(new Read<ArrayList<ComponentTypeViewerSectionFactory>>() {\r
95                         @Override\r
96                         public ArrayList<ComponentTypeViewerSectionFactory> perform(\r
97                                 ReadGraph graph) throws DatabaseException {\r
98                             ArrayList<ComponentTypeViewerSectionFactory> factories =\r
99                                     new ArrayList<ComponentTypeViewerSectionFactory>(3);\r
100                             try {\r
101                                 String className = ComponentTypeViewerSectionFactory.class.getName();\r
102                                 ServiceReference<?>[] references = bundleContext.getAllServiceReferences(className, null);\r
103                                 if(references != null)\r
104                                     for(ServiceReference<?> reference : references) {\r
105                                         ComponentTypeViewerSectionFactory factory = (ComponentTypeViewerSectionFactory)bundleContext.getService(reference);\r
106                                         if(factory.doesSupport(graph, _componentType))\r
107                                             factories.add(factory);\r
108                                     }\r
109                             } catch (InvalidSyntaxException e) {\r
110                                 e.printStackTrace();\r
111                             }\r
112                             return factories;\r
113                         }\r
114                     });\r
115             for(ComponentTypeViewerSectionFactory factory : factories)\r
116                 sections.add(factory.create(data));\r
117         } catch(DatabaseException e) {\r
118             e.printStackTrace();\r
119         }\r
120         \r
121         sections.sort((a,b) -> { return Double.compare(a.getPriority(), b.getPriority()); });\r
122         \r
123         // Sashes\r
124         \r
125         Sash[] sashes = new Sash[sections.size()-1];\r
126         for(int i=0;i<sections.size()-1;++i) {\r
127             Sash sash = new Sash(form.getBody(), SWT.HORIZONTAL);\r
128             sash.setBackground(sash.getDisplay().getSystemColor(SWT.COLOR_WHITE));\r
129             {\r
130                 FormData data = new FormData();\r
131                 data.top = new FormAttachment(100*(i+1)/sections.size(), 0);\r
132                 data.left = new FormAttachment(0, 0);\r
133                 data.right = new FormAttachment(100, 0);\r
134                 data.height = 10;\r
135                 sash.setLayoutData(data);\r
136             }\r
137             sash.addSelectionListener(new SelectionAdapter() {\r
138                 public void widgetSelected(SelectionEvent e) {\r
139                     sash.setBounds(e.x, e.y, e.width, e.height);\r
140                     FormData data = new FormData();\r
141                     data.top = new FormAttachment(0, e.y);\r
142                     data.left = new FormAttachment(0, 0);\r
143                     data.right = new FormAttachment(100, 0);\r
144                     data.height = 10;\r
145                     sash.setLayoutData(data);\r
146                     form.getBody().layout(true);\r
147                 }\r
148             });\r
149             sashes[i] = sash;\r
150         }\r
151         for(int i=0;i<sections.size();++i) {\r
152             {\r
153                 FormData formData = new FormData();\r
154                 formData.top = i > 0 ? new FormAttachment(sashes[i-1]) : new FormAttachment(0, 0);\r
155                 formData.left = new FormAttachment(0, 0);\r
156                 formData.right = new FormAttachment(100, 0);\r
157                 formData.bottom = i < sections.size()-1 \r
158                         ? new FormAttachment(sashes[i]) : new FormAttachment(100, 0);\r
159                 sections.get(i).getSection().setLayoutData(formData);\r
160             }\r
161         }\r
162 \r
163         // Listening\r
164         createGraphListener();\r
165     }\r
166     \r
167     private void createGraphListener() {\r
168         Simantics.getSession().asyncRequest(new UniqueRead<ComponentTypePropertiesResult>() {\r
169             @Override\r
170             public ComponentTypePropertiesResult perform(ReadGraph graph) throws DatabaseException {\r
171                 List<ComponentTypeViewerPropertyInfo> result = new ArrayList<>();\r
172                 List<NamedResource> connectionPoints = new ArrayList<>();\r
173                 Layer0 L0 = Layer0.getInstance(graph);\r
174                 Layer0X L0X = Layer0X.getInstance(graph);\r
175                 StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
176 \r
177                 boolean typeIsImmutable = graph.isImmutable(data.componentType)\r
178                         || graph.hasStatement(data.componentType, STR.ComponentType_Locked)\r
179                         || Layer0Utils.isPublished(graph, data.componentType)\r
180                         || Layer0Utils.isContainerPublished(graph, data.componentType);\r
181 \r
182                 for(Resource relation : graph.getObjects(data.componentType, L0.DomainOf)) {\r
183                     if(graph.isSubrelationOf(relation, L0.HasProperty)) {\r
184                         String name = graph.getRelatedValue(relation, L0.HasName);\r
185                         String type =  graph.getPossibleRelatedValue(relation, L0.RequiresValueType);\r
186                         String label = graph.getPossibleRelatedValue(relation, L0.HasLabel);\r
187                         if (label == null)\r
188                             label = "";\r
189                         String description = graph.getPossibleRelatedValue(relation, L0.HasDescription);\r
190                         if (description == null)\r
191                             description = "";\r
192                         NumberType numberType = null;\r
193                         if(type == null)\r
194                             type = "Double";\r
195                         String unit = graph.getPossibleRelatedValue(relation, L0X.HasUnit, Bindings.STRING);\r
196                         String defaultValue = "0";\r
197                         String expression = null;\r
198                         \r
199                         for(Resource assertion : graph.getAssertedObjects(data.componentType, relation)) {\r
200                             try {\r
201                                 expression = graph.getPossibleRelatedValue(assertion, L0.SCLValue_expression, Bindings.STRING);\r
202                                 if(expression != null) {\r
203                                         defaultValue = "=" + expression;\r
204                                 } else {\r
205                                         Datatype dt = getPossibleDatatype(graph, assertion);\r
206                                         if (dt == null)\r
207                                             continue;\r
208                                         if (dt instanceof NumberType)\r
209                                             numberType = (NumberType) dt;\r
210                                         Binding binding = Bindings.getBinding(dt);\r
211                                         Object value = graph.getValue(assertion, binding);\r
212                                         try {\r
213                                             defaultValue = binding.toString(value, true);\r
214                                         } catch (BindingException e) {\r
215                                             ErrorLogger.defaultLogError(e);\r
216                                         }\r
217                                 }\r
218                             } catch(DatabaseException e) {\r
219                                 ErrorLogger.defaultLogError(e);\r
220                             }\r
221                         }\r
222                         \r
223                         String valid = expression != null ? DerivedPropertiesSection.validateMonitorExpression(graph, data.componentType, relation, expression) : null; \r
224 \r
225                         boolean immutable = typeIsImmutable || graph.isImmutable(relation);\r
226                         ComponentTypeViewerPropertyInfo info =\r
227                                 new ComponentTypeViewerPropertyInfo(relation, name, type, defaultValue, numberType, unit, label, description, expression, valid, immutable);\r
228                         \r
229                         Object sectionSpecificData = null;\r
230                         double priority = Double.NEGATIVE_INFINITY;\r
231                         for(ComponentTypeViewerSection section : sections) {\r
232                             Object temp = section.getSectionSpecificData(graph, info);\r
233                             if(temp != null) {\r
234                                 double sectionPriority = section.getDataPriority();\r
235                                 if(sectionPriority > priority) {\r
236                                     sectionSpecificData = temp;\r
237                                     priority = sectionPriority;\r
238                                 }\r
239                             }\r
240                         }\r
241                         info.sectionSpecificData = sectionSpecificData;\r
242                         \r
243                         result.add(info);\r
244 \r
245                     } else if (graph.isInstanceOf(relation, STR.ConnectionRelation)) {\r
246                         NamedResource nr = new NamedResource(NameUtils.getSafeName(graph, relation), relation);\r
247                         connectionPoints.add(nr);\r
248                     }\r
249                 }\r
250                 Collections.sort(result);\r
251                 return new ComponentTypePropertiesResult(result, connectionPoints, typeIsImmutable);\r
252             }\r
253         }, new Listener<ComponentTypePropertiesResult>() {\r
254             @Override\r
255             public void execute(final ComponentTypePropertiesResult result) {  \r
256                 SWTUtils.asyncExec(data.form.getDisplay(), new Runnable() {\r
257                     @Override\r
258                     public void run() {\r
259                         // Store loaded properties\r
260                         data.properties = result.getProperties().toArray(new ComponentTypeViewerPropertyInfo[result.getProperties().size()]);\r
261                         data.connectionPoints = result.getConnectionPoints().toArray(new NamedResource[result.getConnectionPoints().size()]);\r
262 \r
263                         for(ComponentTypeViewerSection section : sections)\r
264                             section.update(result);\r
265                         setReadOnly(result.isImmutable());\r
266                     }\r
267                 });\r
268             }\r
269 \r
270             @Override\r
271             public void exception(Throwable t) {\r
272                 ErrorLogger.defaultLogError(t);\r
273             }\r
274 \r
275             @Override\r
276             public boolean isDisposed() {\r
277                 return data.form.isDisposed();\r
278             }\r
279 \r
280         });\r
281     }\r
282 \r
283     protected Datatype getPossibleDatatype(ReadGraph graph, Resource literal) throws DatabaseException {\r
284         Binding binding = Bindings.getBindingUnchecked(Datatype.class);\r
285         for (Resource dataTypeResource : graph.getObjects(literal, Layer0.getInstance(graph).HasDataType)) {\r
286             Datatype dt = graph.getPossibleValue(dataTypeResource, binding);\r
287             if (dt != null)\r
288                 return dt;\r
289         }\r
290         return null;\r
291     }\r
292 \r
293     public void setFocus() {\r
294         data.form.setFocus();\r
295     }\r
296 \r
297     /**\r
298      * @param readOnly\r
299      * @thread SWT\r
300      */\r
301     private void setReadOnly(boolean readOnly) {\r
302         if (readOnly == data.readOnly)\r
303             return;\r
304         data.readOnly = readOnly;\r
305         for(ComponentTypeViewerSection section : sections)\r
306             section.setReadOnly(readOnly);\r
307         IMessageManager mm = data.form.getMessageManager();\r
308         if (readOnly)\r
309             mm.addMessage("readonly", "(Opened in read-only mode)", null, IMessageProvider.INFORMATION);\r
310         else\r
311             mm.removeMessage("readonly");\r
312     }\r
313 \r
314 }\r