]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/FlagClassFactory.java
Logger fixes after merge commit:fdbe8762
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / adapter / FlagClassFactory.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in 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.diagram.adapter;\r
13 \r
14 import java.awt.Shape;\r
15 import java.awt.geom.AffineTransform;\r
16 import java.awt.geom.Rectangle2D;\r
17 import java.util.ArrayList;\r
18 import java.util.Collection;\r
19 import java.util.Collections;\r
20 import java.util.List;\r
21 import java.util.Map;\r
22 import java.util.regex.Pattern;\r
23 import java.util.regex.PatternSyntaxException;\r
24 \r
25 import org.simantics.databoard.Bindings;\r
26 import org.simantics.databoard.binding.error.RuntimeBindingConstructionException;\r
27 import org.simantics.databoard.util.Bean;\r
28 import org.simantics.datatypes.literal.Font;\r
29 import org.simantics.datatypes.literal.RGB;\r
30 import org.simantics.db.AsyncReadGraph;\r
31 import org.simantics.db.ReadGraph;\r
32 import org.simantics.db.Resource;\r
33 import org.simantics.db.Session;\r
34 import org.simantics.db.WriteGraph;\r
35 import org.simantics.db.common.procedure.adapter.TransientCacheListener;\r
36 import org.simantics.db.common.request.ResourceRead;\r
37 import org.simantics.db.common.request.TernaryRead;\r
38 import org.simantics.db.common.request.WriteRequest;\r
39 import org.simantics.db.exception.DatabaseException;\r
40 import org.simantics.db.layer0.variable.Variable;\r
41 import org.simantics.db.layer0.variable.Variables;\r
42 import org.simantics.db.procedure.AsyncProcedure;\r
43 import org.simantics.diagram.content.ResourceTerminal;\r
44 import org.simantics.diagram.flag.AbstractFlagType;\r
45 import org.simantics.diagram.flag.BasicFlagType;\r
46 import org.simantics.diagram.flag.FlagSceneGraph;\r
47 import org.simantics.diagram.flag.FlagUtil;\r
48 import org.simantics.diagram.flag.IFlagType;\r
49 import org.simantics.diagram.flag.IFlagType.FlagInfo;\r
50 import org.simantics.diagram.flag.IFlagTypeReader;\r
51 import org.simantics.diagram.function.All;\r
52 import org.simantics.diagram.function.PredefinedVariables;\r
53 import org.simantics.diagram.query.DiagramRequests;\r
54 import org.simantics.diagram.query.FlagTables;\r
55 import org.simantics.diagram.query.FlagTypeFilter;\r
56 import org.simantics.diagram.query.FlagTypeFilters;\r
57 import org.simantics.diagram.query.FlagTypeVisual;\r
58 import org.simantics.diagram.query.FlagTypeVisuals;\r
59 import org.simantics.diagram.stubs.DiagramResource;\r
60 import org.simantics.diagram.synchronization.CompositeHintSynchronizer;\r
61 import org.simantics.diagram.synchronization.IHintSynchronizer;\r
62 import org.simantics.diagram.synchronization.SynchronizationHints;\r
63 import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;\r
64 import org.simantics.diagram.synchronization.graph.FlagSynchronizer;\r
65 import org.simantics.diagram.synchronization.graph.TransformSynchronizer;\r
66 import org.simantics.diagram.ui.DiagramModelHints;\r
67 import org.simantics.g2d.canvas.ICanvasContext;\r
68 import org.simantics.g2d.diagram.IDiagram;\r
69 import org.simantics.g2d.diagram.handler.Topology.Terminal;\r
70 import org.simantics.g2d.element.ElementClass;\r
71 import org.simantics.g2d.element.ElementUtils;\r
72 import org.simantics.g2d.element.IElement;\r
73 import org.simantics.g2d.element.handler.TextEditor;\r
74 import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;\r
75 import org.simantics.g2d.elementclass.FlagClass;\r
76 import org.simantics.g2d.elementclass.FlagClass.Mode;\r
77 import org.simantics.g2d.elementclass.FlagHandler;\r
78 import org.simantics.g2d.utils.Alignment;\r
79 import org.simantics.g2d.utils.geom.DirectionSet;\r
80 import org.simantics.layer0.Layer0;\r
81 import org.simantics.modeling.ModelingResources;\r
82 import org.simantics.modeling.template2d.ontology.Template2dResource;\r
83 import org.simantics.structural2.modelingRules.IModelingRules;\r
84 import org.simantics.utils.ui.ErrorLogger;\r
85 \r
86 /**\r
87  * @author Tuukka Lehtonen\r
88  */\r
89 public class FlagClassFactory extends SyncElementFactory {\r
90 \r
91     private static final Bean[] NO_BEANS = {};\r
92 \r
93     private static final IHintSynchronizer HINT_SYNCHRONIZER = new CompositeHintSynchronizer(FlagSynchronizer.INSTANCE, TransformSynchronizer.INSTANCE);\r
94 \r
95     public static ElementClass createFlagClass(Resource elementClass, Resource terminalResource) {\r
96         Terminal terminal = new ResourceTerminal(terminalResource, new AffineTransform(), DirectionSet.ANY);\r
97         return FlagClass.create(terminal, FlagSceneGraph.INSTANCE).newClassWith(new StaticObjectAdapter(elementClass));\r
98     }\r
99 \r
100     @Override\r
101     public void create(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementType, AsyncProcedure<ElementClass> procedure) {\r
102         DiagramResource DIA = graph.getService(DiagramResource.class);\r
103         procedure.execute(graph, createFlagClass(DIA.Flag, DIA.Flag_Terminal));\r
104     }\r
105 \r
106     @Override\r
107     public void load(ReadGraph g, ICanvasContext canvas, IDiagram diagram, Resource flag, IElement e) throws DatabaseException {\r
108         Layer0 l0 = g.getService(Layer0.class);\r
109         DiagramResource dr = g.getService(DiagramResource.class);\r
110 \r
111         ElementClass ec = e.getElementClass();\r
112         final FlagHandler fh = ec.getSingleItem(FlagHandler.class);\r
113 \r
114         fh.connectData(e, flag, FlagUtil.getPossibleCounterpart(g, flag));\r
115         fh.setExternal(e, FlagUtil.isExternal(g, flag));\r
116 \r
117         TextEditor ed = ec.getAtMostOneItemOfClass(TextEditor.class);\r
118         if (ed != null) {\r
119             final Session session = g.getSession();\r
120             ed.setModifier(e, new TextEditor.Modifier() {\r
121                 @Override\r
122                 public String getValue(IElement element) {\r
123                     String s = ElementUtils.getText(element);\r
124                     return s != null ? s : "";\r
125                 }\r
126 \r
127                 @Override\r
128                 public String isValid(IElement element, String text) {\r
129                     return null;\r
130                 }\r
131 \r
132                 @Override\r
133                 public void modify(final IElement element, final String text) {\r
134                     final Resource flag = (Resource) ElementUtils.getObject(element);\r
135                     try {\r
136                         session.syncRequest(new WriteRequest() {\r
137                             @Override\r
138                             public void perform(WriteGraph graph) throws DatabaseException {\r
139                                 Layer0 l0 = Layer0.getInstance(graph);\r
140                                 DiagramGraphUtil.setRelatedValue(graph, flag, l0.HasLabel, l0.String, text, Bindings.STRING);\r
141                                 Resource otherFlag = FlagUtil.getPossibleCounterpart(graph, flag);\r
142                                 if (otherFlag != null)\r
143                                     DiagramGraphUtil.setRelatedValue(graph, otherFlag, l0.HasLabel, l0.String, text, Bindings.STRING);\r
144                             }\r
145                         });\r
146                     } catch (DatabaseException e) {\r
147                         ErrorLogger.defaultLogError("Flag label editing failed, see exception for details.", e);\r
148                     }\r
149                 }\r
150             });\r
151         }\r
152 \r
153         Resource diagramRuntime = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RUNTIME_RESOURCE);\r
154         AffineTransform at = DiagramGraphUtil.getDynamicAffineTransform(g, diagramRuntime, flag);\r
155         ElementUtils.setTransform(e, at);\r
156 \r
157         String label = g.getPossibleRelatedValue(flag, l0.HasLabel);\r
158         if (label == null)\r
159             label = "";\r
160         ElementUtils.setText(e, label);\r
161 \r
162         boolean shapeIsSet = false;\r
163         boolean flagTextIsSet = false;\r
164         boolean flagTypeIsSet = false;\r
165         boolean textAreaIsSet = false;\r
166 \r
167         // Defaults\r
168         e.setHint(FlagClass.KEY_TEXT_HORIZONTAL_ALIGN, Alignment.LEADING);\r
169         e.setHint(FlagClass.KEY_TEXT_VERTICAL_ALIGN, Alignment.CENTER);\r
170 \r
171         IModelingRules modelingRules = diagram.getHint(DiagramModelHints.KEY_MODELING_RULES);\r
172         if (modelingRules != null) {\r
173             Resource connectionType = DiagramGraphUtil.getConnectionTypeForFlag(g, flag);\r
174             IFlagTypeReader ftr = null;\r
175             if (connectionType != null) {\r
176                 //System.out.println("FLAG " + NameUtils.getSafeName(g, flag) + ", CONNECTION TYPE " + NameUtils.getSafeName(g, connectionType));\r
177                 ftr = g.getPossibleAdapter(connectionType, IFlagTypeReader.class);\r
178             }\r
179             if (ftr == null) {\r
180                 //System.out.println("FLAG " + NameUtils.getSafeName(g, flag) + ", NO CONNECTION TYPE");\r
181                 ftr = g.getPossibleAdapter(flag, IFlagTypeReader.class);\r
182             }\r
183 \r
184             if (ftr != null) {\r
185                 IFlagType ft = ftr.read(g, flag, modelingRules);\r
186 \r
187                 FlagInfo info = ft.getInfo(g);\r
188 \r
189                 Shape shape = info.getShape();\r
190                 if (shape != null) {\r
191                     e.setHint(FlagClass.KEY_SHAPE, shape);\r
192                     shapeIsSet = true;\r
193                 }\r
194 \r
195                 FlagClass.Type type = info.getType();\r
196                 if (type != null) {\r
197                     e.setHint(FlagClass.KEY_FLAG_TYPE, type);\r
198                     flagTypeIsSet = true;\r
199                 }\r
200 \r
201                 String[] flagText = info.getText();\r
202                 if (flagText != null) {\r
203                     e.setHint(FlagClass.KEY_FLAG_TEXT, flagText);\r
204                     flagTextIsSet = true;\r
205                 }\r
206 \r
207                 if (info.getTextArea() != null) {\r
208                     e.setHint(FlagClass.KEY_FLAG_TEXT_AREA, info.getTextArea());\r
209                     textAreaIsSet = true;\r
210                 }\r
211 \r
212                 if (info.getHorizontalAlignment() != null)\r
213                     e.setHint(FlagClass.KEY_TEXT_HORIZONTAL_ALIGN, info.getHorizontalAlignment());\r
214                 if (info.getVerticalAlignment() != null)\r
215                     e.setHint(FlagClass.KEY_TEXT_VERTICAL_ALIGN, info.getVerticalAlignment());\r
216             }\r
217         }\r
218 \r
219         if (!flagTypeIsSet)\r
220             // Fall back to reading flag type from a property.\r
221             e.setHint(FlagClass.KEY_FLAG_TYPE, DiagramGraphUtil.toFlagType(dr, g.getPossibleObject(flag, dr.HasFlagType), FlagClass.Type.In));\r
222         if (!flagTextIsSet)\r
223 //            e.setHint(FlagClass.KEY_FLAG_TEXT, new String[] { label });\r
224             e.setHint(FlagClass.KEY_FLAG_TEXT, g.syncRequest(DiagramRequests.getFlagText(flag)));\r
225         if (!textAreaIsSet) {\r
226             FlagClass.Type type = e.getHint(FlagClass.KEY_FLAG_TYPE);\r
227             Mode mode = AbstractFlagType.getMode(g, flag);\r
228             e.setHint(FlagClass.KEY_FLAG_TEXT_AREA, BasicFlagType.getArea(type, mode));\r
229         }\r
230         if (!shapeIsSet) {\r
231             FlagClass.Type type = e.getHint(FlagClass.KEY_FLAG_TYPE);\r
232             Mode mode = AbstractFlagType.getMode(g, flag);\r
233             e.setHint(FlagClass.KEY_SHAPE, BasicFlagType.getShape(type, mode));\r
234         }\r
235 \r
236         e.setHint(SynchronizationHints.HINT_SYNCHRONIZER, HINT_SYNCHRONIZER);\r
237         e.setHint(FlagSceneGraph.KEY_FLAG_VISUALS, NO_BEANS);\r
238 \r
239         DiagramResource DIA = DiagramResource.getInstance(g);\r
240         Layer0 L0 = Layer0.getInstance(g);\r
241 \r
242         Resource template = diagramRuntime != null ? All.getTemplate(g, diagramRuntime) : null;\r
243         Resource flagTable = getFlagTable(g, template, flag);\r
244 \r
245         if (template != null && flagTable != null) {\r
246 \r
247             Resource flagTypeVisual = getVisualOfFlag(g, template, flagTable, flag);\r
248             if (flagTypeVisual != null) {\r
249                 Template2dResource TEMPLATE2D = Template2dResource.getInstance(g);\r
250                 float tableWidth = g.getRelatedValue(flagTable, TEMPLATE2D.FlagTable_HasWidth, Bindings.FLOAT);\r
251                 Resource align = g.getPossibleObject(flagTable, TEMPLATE2D.FlagTable_HasAlignment);\r
252                 float height = g.getRelatedValue(flagTable, TEMPLATE2D.FlagTable_HasRowHeigth, Bindings.FLOAT);\r
253                 float halfHeight = height / 2;\r
254                 float horizontalOffset = tableWidth;\r
255 \r
256                 if (align != null) {\r
257                     if (align.equals(TEMPLATE2D.FlagTable_Alignment_Left)) {\r
258                         horizontalOffset = 0.0f;\r
259                     } else if (align.equals(TEMPLATE2D.FlagTable_Alignment_Right)) {\r
260                         tableWidth = -tableWidth;\r
261                         horizontalOffset = -horizontalOffset;\r
262                     }\r
263                 }\r
264 \r
265                 Collection<Resource> monitorsAndTexts = g.getObjects(flagTypeVisual, L0.ConsistsOf);\r
266                 List<Bean> flagVisuals = Collections.emptyList(); \r
267                 if (!monitorsAndTexts.isEmpty()) {\r
268                     flagVisuals = new ArrayList<Bean>(monitorsAndTexts.size());\r
269 \r
270                     ModelingResources MOD = ModelingResources.getInstance(g);\r
271                     Resource diagramResource = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RESOURCE);\r
272                     Resource compositeResource = g.getSingleObject(diagramResource, MOD.DiagramToComposite);\r
273                     Variable compositeVariable = Variables.getVariable(g, compositeResource);\r
274 \r
275                     for (Resource visual : monitorsAndTexts) {\r
276                         if (!acceptVisual(g, flag, visual))\r
277                             continue;\r
278 \r
279                         if (g.isInstanceOf(visual, DIA.Scenegraph_Monitor)) {\r
280                             FlagTextInfo i = g.syncRequest(new ReadFlagTextInfo(visual), TransientCacheListener.<FlagTextInfo>instance());\r
281                             FlagTextInfo monitorInfo = (FlagTextInfo) i.clone();\r
282                             if (monitorInfo.transform != null)\r
283                                 monitorInfo.transform[4] += horizontalOffset;\r
284 \r
285                             String path = g.getRelatedValue(visual, DIA.Scenegraph_Monitor_reference, Bindings.STRING);\r
286                             String value = "";\r
287                             if (path != null && path.length() > 0) {\r
288                                 value = evaluatePath(g,flag,path);\r
289                             }\r
290                             monitorInfo.text = value;\r
291                             monitorInfo.id = Long.toString(visual.getResourceId());\r
292 \r
293                             flagVisuals.add(monitorInfo);\r
294                         } else if (g.isInstanceOf(visual, DIA.Scenegraph_Text)) {\r
295                             FlagTextInfo i = g.syncRequest(new ReadFlagTextInfo(visual), TransientCacheListener.<FlagTextInfo>instance());\r
296                             FlagTextInfo info = (FlagTextInfo) i.clone();\r
297                             if (info.transform != null)\r
298                                 info.transform[4] += horizontalOffset;\r
299 \r
300                             String path = g.getRelatedValue(visual, DIA.Scenegraph_Text_text, Bindings.STRING);\r
301                             if (path != null && path.length() > 0) {\r
302                                 info.text = path;\r
303                             }\r
304                             info.id = Long.toString(visual.getResourceId());\r
305 \r
306                             flagVisuals.add(info);\r
307                         } else if (g.isInstanceOf(visual, DIA.Scenegraph_SVGImage)) {\r
308                             SVGImageInfo info = g.syncRequest(new ReadSVGImageInfo(visual, compositeResource, compositeVariable), TransientCacheListener.<SVGImageInfo>instance());\r
309                             flagVisuals.add(info);\r
310                         }\r
311                     }\r
312                 }\r
313 \r
314                 if (flagVisuals.size() > 0) {\r
315                     // Make sure that the flag shape is set to something that\r
316                     // should contain the flag visual to make selection borders\r
317                     // work properly.\r
318                     Rectangle2D newShape = new Rectangle2D.Double();\r
319                     newShape.setFrameFromDiagonal(0, -halfHeight, tableWidth, halfHeight);\r
320                     e.setHint(FlagClass.KEY_SHAPE, newShape);\r
321                     e.setHint(FlagSceneGraph.KEY_FLAG_VISUALS, flagVisuals.toArray(NO_BEANS));\r
322                 }\r
323             }\r
324         }\r
325     }\r
326 \r
327     private static String evaluatePath(ReadGraph graph, Resource resource, String path) throws DatabaseException{\r
328         Variable resourceVariable = Variables.getPossibleVariable(graph, resource);\r
329         if (resourceVariable == null)\r
330             return "";\r
331         return evaluatePath(graph, resource, resourceVariable, path);\r
332     }\r
333 \r
334     private static String evaluatePath(ReadGraph graph, Resource resource, Variable resourceVariable, String path) throws DatabaseException{\r
335         PredefinedVariables vars = PredefinedVariables.getInstance();\r
336         Variable property = vars.getVariable(graph, path, resource, resourceVariable);\r
337         if (property == null)\r
338             return "";\r
339         Object value = property.getPossibleValue(graph);\r
340         if (value == null || !(value instanceof String))\r
341             return "";\r
342         return value.toString();\r
343     }\r
344 \r
345     static class ReadSVGImageInfo extends TernaryRead<Resource, Resource, Variable, SVGImageInfo> {\r
346 \r
347         public ReadSVGImageInfo(Resource svgImageNode, Resource composite, Variable compositeVariable) {\r
348             super(svgImageNode, composite, compositeVariable);\r
349         }\r
350 \r
351         @Override\r
352         public SVGImageInfo perform(ReadGraph graph) throws DatabaseException {\r
353             SVGImageInfo info = new SVGImageInfo();\r
354             DiagramResource DIA = DiagramResource.getInstance(graph);\r
355             info.id = Long.toString(parameter.getResourceId());\r
356             Resource document = graph.getPossibleObject(parameter, DIA.Scenegraph_SVGImage_document);\r
357             if (document != null) {\r
358                 Template2dResource TMPL = Template2dResource.getInstance(graph);\r
359                 String path = graph.getPossibleRelatedValue(document, TMPL.Profiles_VariableReference_path, Bindings.STRING);\r
360                 if (path != null) {\r
361                     String svg = evaluatePath(graph, parameter2, parameter3, path);\r
362                     if (svg != null && !svg.isEmpty())\r
363                         info.svgDocument = svg;\r
364                     //System.out.println("svgDocument: " + info.svgDocument);\r
365                 }\r
366             }\r
367             info.transform = graph.getPossibleRelatedValue(parameter, DIA.Scenegraph_SVGImage_transform, Bindings.DOUBLE_ARRAY);\r
368             return info;\r
369         }\r
370 \r
371     }\r
372 \r
373     static class ReadFlagTextInfo extends ResourceRead<FlagTextInfo> {\r
374 \r
375         public ReadFlagTextInfo(Resource textNode) {\r
376             super(textNode);\r
377         }\r
378 \r
379         @Override\r
380         public FlagTextInfo perform(ReadGraph graph) throws DatabaseException {\r
381             return createTextInfo(graph, resource);\r
382         }\r
383 \r
384     }\r
385 \r
386     /**\r
387      * @param g\r
388      * @param visual\r
389      * @return\r
390      * @throws DatabaseException\r
391      * @throws RuntimeBindingConstructionException\r
392      */\r
393     private static FlagTextInfo createTextInfo(ReadGraph g, Resource visual) throws DatabaseException {\r
394         DiagramResource DIA = DiagramResource.getInstance(g);\r
395         //Template2d TEMPLATE2D = Template2d.getInstance(g);\r
396         //Layer0 L0 = Layer0.getInstance(g);\r
397 \r
398         FlagTextInfo info = new FlagTextInfo();\r
399         info.id = Long.toString(visual.getResourceId());\r
400 \r
401         info.font = g.getPossibleRelatedValue2(visual, DIA.Scenegraph_AbstractText_font, Bindings.getBindingUnchecked(Font.class));\r
402         info.color = g.getPossibleRelatedValue2(visual, DIA.Scenegraph_AbstractText_color, RGB.Integer.BINDING/*Bindings.getBindingUnchecked(RGB.Integer.class)*/);\r
403         info.borderColor = g.getPossibleRelatedValue2(visual, DIA.Scenegraph_AbstractText_borderColor, RGB.Integer.BINDING/*Bindings.getBindingUnchecked(RGB.Integer.class)*/);\r
404         info.backgroundColor = g.getPossibleRelatedValue2(visual, DIA.Scenegraph_AbstractText_backgroundColor, RGB.Integer.BINDING/*Bindings.getBindingUnchecked(RGB.Integer.class)*/);\r
405         Float width = g.getPossibleRelatedValue2(visual, DIA.Scenegraph_AbstractText_width, Bindings.getBindingUnchecked(Float.class));\r
406         if (width != null)\r
407             info.width = width;\r
408 \r
409         Float borderWidth = g.getPossibleRelatedValue2(visual, DIA.Scenegraph_AbstractText_borderWidth, Bindings.getBindingUnchecked(Float.class));\r
410         if (borderWidth != null)\r
411             info.borderWidth = borderWidth;\r
412 \r
413         Boolean wrapText = g.getRelatedValue2(visual, DIA.Scenegraph_AbstractText_wrapText, Bindings.BOOLEAN);\r
414         if (wrapText != null)\r
415             info.wrapText = wrapText; \r
416 \r
417         info.hAlignment = Alignment.LEADING;\r
418         Byte hAlignment = g.getPossibleRelatedValue2(visual, DIA.Scenegraph_AbstractText_horizontalAlignment, Bindings.BYTE);\r
419         if (hAlignment != null) {\r
420             if (hAlignment == 1)\r
421                 info.hAlignment = Alignment.TRAILING;\r
422             else if (hAlignment == 2)\r
423                 info.hAlignment = Alignment.CENTER;\r
424         }\r
425 \r
426         info.vAlignment = Alignment.LEADING;\r
427         Byte vAlignment = g.getPossibleRelatedValue2(visual, DIA.Scenegraph_AbstractText_verticalAlignment, Bindings.BYTE);\r
428         if (vAlignment != null) {\r
429             if (vAlignment == 1)\r
430                 info.vAlignment = Alignment.TRAILING;\r
431             else if (vAlignment == 2)\r
432                 info.vAlignment = Alignment.CENTER;\r
433             else if (vAlignment == 3)\r
434                 info.vAlignment = Alignment.BASELINE;\r
435         }\r
436 \r
437         info.transform = g.getPossibleRelatedValue2(visual, DIA.Scenegraph_AbstractText_transform, Bindings.getBindingUnchecked(double[].class));\r
438         return info;\r
439     }\r
440 \r
441     private static Resource getFlagTable(ReadGraph g, Resource template, Resource flag) throws DatabaseException {\r
442         if (template == null || flag == null)\r
443             return null;\r
444 \r
445         DiagramResource DIA = DiagramResource.getInstance(g);\r
446         String tableName = g.getPossibleRelatedValue(flag, DIA.Flag_HasIOTableBinding, Bindings.STRING);\r
447         if (tableName == null)\r
448             return null;\r
449 \r
450         Map<String, Resource> flagTables = g.syncRequest(new FlagTables(template), TransientCacheListener.<Map<String, Resource>>instance());\r
451         return flagTables.get(tableName);\r
452     }\r
453 \r
454     private Resource getVisualOfFlag(ReadGraph g, Resource template, Resource flagTable, Resource flag) throws DatabaseException {\r
455         if (template == null || flagTable == null || flag == null)\r
456             return null;\r
457 \r
458         // First make sure that there are possible visuals.\r
459         // There's no point in proceeding if no visuals exist.\r
460         List<FlagTypeVisual> flagTypeVisuals = g.syncRequest( new FlagTypeVisuals(flagTable),\r
461                 TransientCacheListener.<List<FlagTypeVisual>>instance());\r
462         if (flagTypeVisuals == null || flagTypeVisuals.isEmpty())\r
463             return null;\r
464 \r
465         Variable flagVariable = Variables.getPossibleVariable(g, flag);\r
466         if (flagVariable == null)\r
467             return null;\r
468 \r
469         for (FlagTypeVisual visual : flagTypeVisuals) {\r
470             Resource visualComposite = visual.getVisualComposite();\r
471 \r
472             String filterReference = visual.getFilteredPropertyReference();\r
473             if (filterReference == null || filterReference.isEmpty())\r
474                 return visualComposite;\r
475 \r
476             String filterPattern = visual.getFilterPattern();\r
477             if (filterPattern == null || filterPattern.isEmpty())\r
478                 return visualComposite;\r
479 \r
480             String value = evaluatePath(g, flag, flagVariable, filterReference);\r
481             if (value == null)\r
482                 return visualComposite;\r
483 \r
484             try {\r
485                 if (!Pattern.matches(filterPattern, value)) {\r
486                     // filter is defined but property don't match\r
487                     continue;\r
488                 }\r
489             } catch (PatternSyntaxException ex) {\r
490                 ErrorLogger.defaultLogError(ex);\r
491                 continue;\r
492             }\r
493 \r
494             return visualComposite;\r
495         }\r
496 \r
497         return null;\r
498     }\r
499 \r
500     /**\r
501      * @param graph\r
502      * @param flag the flag to which to apply the filter reference paths\r
503      * @param visual the visual to look for filters from\r
504      * @return <code>true</code> if filter passes, <code>false</code> if not\r
505      * @throws DatabaseException\r
506      */\r
507     private boolean acceptVisual(ReadGraph graph, Resource flag, Resource visual) throws DatabaseException {\r
508         List<FlagTypeFilter> filters = graph.syncRequest(new FlagTypeFilters(visual),\r
509                 TransientCacheListener.<List<FlagTypeFilter>>instance());\r
510         if (filters.isEmpty())\r
511             return true;\r
512 \r
513         Variable flagVariable = Variables.getPossibleVariable(graph, flag);\r
514         if (flagVariable == null)\r
515             return false;\r
516 \r
517         for (FlagTypeFilter filter : filters) {\r
518             String reference = filter.getReference();\r
519             if (reference == null || reference.isEmpty())\r
520                 continue;\r
521 \r
522             String pattern = filter.getPattern();\r
523             if (pattern == null || pattern.isEmpty())\r
524                 continue;\r
525 \r
526             String value = evaluatePath(graph, flag, flagVariable, reference);\r
527             if (value == null)\r
528                 continue;\r
529 \r
530             try {\r
531                 if (Pattern.matches(pattern, value) == filter.isMatchRequired()) {\r
532                     return true;\r
533                 }\r
534             } catch (PatternSyntaxException ex) {\r
535                 ErrorLogger.defaultLogError(ex);\r
536                 continue;\r
537             }\r
538         }\r
539 \r
540         return false;\r
541     }\r
542 \r
543 }