524bf294b91b05a99df399b22231a1ecb2096d6c
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / mapping / ComponentCopyAdvisor.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.modeling.mapping;\r
13 \r
14 import gnu.trove.map.hash.THashMap;\r
15 \r
16 import java.util.Map;\r
17 \r
18 import org.simantics.Simantics;\r
19 import org.simantics.databoard.Bindings;\r
20 import org.simantics.datatypes.literal.GUID;\r
21 import org.simantics.db.Resource;\r
22 import org.simantics.db.WriteGraph;\r
23 import org.simantics.db.exception.DatabaseException;\r
24 import org.simantics.diagram.synchronization.ISynchronizationContext;\r
25 import org.simantics.diagram.synchronization.SynchronizationException;\r
26 import org.simantics.diagram.synchronization.SynchronizationHints;\r
27 import org.simantics.diagram.synchronization.graph.BasicResources;\r
28 import org.simantics.diagram.synchronization.graph.CopyAdvisorUtil;\r
29 import org.simantics.diagram.synchronization.graph.GraphCopyAdvisor;\r
30 import org.simantics.diagram.synchronization.graph.GraphSynchronizationHints;\r
31 import org.simantics.layer0.Layer0;\r
32 import org.simantics.modeling.ComponentUtils;\r
33 import org.simantics.modeling.services.ComponentNamingUtil;\r
34 import org.simantics.modeling.services.NamingException;\r
35 import org.simantics.project.IProject;\r
36 import org.simantics.structural.stubs.StructuralResource2;\r
37 \r
38 /**\r
39  * @author Tuukka Lehtonen\r
40  */\r
41 public class ComponentCopyAdvisor extends GraphCopyAdvisor {\r
42 \r
43     @Override\r
44     public Evaluation canCopy(ISynchronizationContext context, WriteGraph graph, Resource source,\r
45             Resource sourceContainer, Resource targetContainer) throws DatabaseException {\r
46         BasicResources br = context.get(GraphSynchronizationHints.BASIC_RESOURCES);\r
47         return (graph.isInstanceOf(source, br.STR.Component) || graph.isInstanceOf(source, br.STR.Connection))\r
48         ? Evaluation.SUPPORTED : Evaluation.NOT_SUPPORTED;\r
49     }\r
50 \r
51     @Override\r
52     public Object copy(ISynchronizationContext context, WriteGraph graph, Resource source, Resource sourceContainer,\r
53             Resource targetContainer) throws DatabaseException {\r
54         return copy(context, graph, source, sourceContainer, targetContainer, new THashMap<Object, Object>());\r
55     }\r
56 \r
57     @Override\r
58     public Object copy(ISynchronizationContext context, WriteGraph graph, Resource source, Resource sourceContainer,\r
59             Resource targetContainer, Map<Object, Object> map) throws DatabaseException {\r
60         StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
61         Resource copy = null;\r
62         if (graph.isInstanceOf(source, STR.Connection)) {\r
63             // Configuration connections are not named, can't use TG copy for\r
64             // them at the moment.\r
65             copy = CopyAdvisorUtil.copy2(graph, source, null, map);\r
66         } else {\r
67 //            Resource model = graph.syncRequest(new PossibleModel(targetContainer));\r
68 //            copy = CopyAdvisorUtil.copy4(graph, source, model);\r
69             copy = CopyAdvisorUtil.copy2(graph, source, null, map);\r
70         }\r
71 \r
72         Layer0 L0 = Layer0.getInstance(graph);\r
73         if (graph.hasStatement(sourceContainer, L0.ConsistsOf, source))\r
74             graph.claim(targetContainer, L0.ConsistsOf, copy);\r
75 \r
76         graph.claimLiteral(copy, L0.identifier, L0.identifier_Inverse, L0.GUID, GUID.random(), GUID.BINDING);\r
77         if (context.get(SynchronizationHints.NO_RENAME) == null)\r
78             renameComponent(context, graph, source, copy, sourceContainer, targetContainer);\r
79         return copy;\r
80     }\r
81 \r
82     public static String renameComponent(ISynchronizationContext context, WriteGraph graph, Resource source,\r
83             Resource copy, Resource sourceContainer, Resource targetContainer) throws DatabaseException {\r
84         return renameComponent(context, graph, source, copy, sourceContainer, targetContainer,\r
85                 Layer0.getInstance(graph).HasName);\r
86     }\r
87 \r
88     public static String renameComponent(ISynchronizationContext context, WriteGraph graph, Resource source,\r
89             Resource copy, Resource sourceContainer, Resource targetContainer, Resource nameProperty)\r
90             throws DatabaseException {\r
91         BasicResources br = context.get(GraphSynchronizationHints.BASIC_RESOURCES);\r
92 \r
93         Resource sourceComponentType = graph.getPossibleType(source, br.STR.Component);\r
94         if (sourceComponentType == null)\r
95             return null;\r
96 \r
97         // Try to obtain a ComponentNamingStrategy for renaming the copied object.\r
98         IProject project = context.get(SynchronizationHints.PROJECT);\r
99         if (project == null)\r
100             project = Simantics.getProject();\r
101 \r
102         // Try to give a valid or at least unique name for the new component.\r
103         //Resource configurationRoot = ComponentUtils.getComponentConfigurationRoot(graph, copy);\r
104         //Resource composite = ComponentUtils.tryGetComponentContainer(graph, copy);\r
105         Resource configurationRoot = ComponentUtils.getCompositeConfigurationRoot(graph, targetContainer);\r
106         Resource composite = targetContainer;\r
107 \r
108         if (configurationRoot != null) {\r
109             try {\r
110                 String name = ComponentNamingUtil.findFreshInstanceName(graph, project, configurationRoot, composite, sourceComponentType);\r
111                 graph.claimLiteral(copy, nameProperty, name, Bindings.STRING);\r
112                 return name;\r
113             } catch (NamingException e) {\r
114                 // This will produce duplicate names in the model,\r
115                 // should not happen if we don't run out of names.\r
116                 throw new SynchronizationException(e);\r
117             }\r
118         }\r
119         return null;\r
120     }\r
121 \r
122     @Override\r
123     public Object cut(ISynchronizationContext context, WriteGraph graph, Resource source, Resource sourceContainer,\r
124             Resource targetContainer) throws DatabaseException {\r
125         Layer0 L0 = Layer0.getInstance(graph);\r
126 \r
127         if (sourceContainer.equals(targetContainer))\r
128             return null;\r
129 \r
130         // This handles e.g. connections, which are not part of container\r
131         if(graph.hasStatement(sourceContainer, L0.ConsistsOf, source)) {\r
132             graph.deny(sourceContainer, L0.ConsistsOf, source);\r
133             graph.claim(targetContainer, L0.ConsistsOf, source);\r
134         }\r
135 \r
136         return source;\r
137     }\r
138 \r
139 }\r