]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling/src/org/simantics/modeling/adapters/CompositeCopyHandler.java
ae65e87f88476bf6b2059e8899d5a63266816fee
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / adapters / CompositeCopyHandler.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.modeling.adapters;
13
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.HashSet;
17 import java.util.List;
18 import java.util.Set;
19
20 import org.simantics.db.ReadGraph;
21 import org.simantics.db.Resource;
22 import org.simantics.db.common.request.ObjectsWithType;
23 import org.simantics.db.common.request.PossibleIndexRoot;
24 import org.simantics.db.exception.DatabaseException;
25 import org.simantics.db.layer0.adapter.SubgraphExtent.ExtentStatus;
26 import org.simantics.db.layer0.adapter.impl.DefaultCopyHandler;
27 import org.simantics.db.layer0.util.TransferableGraphConfiguration2;
28 import org.simantics.db.layer0.util.TransferableGraphConfiguration2.RootSpec;
29 import org.simantics.diagram.stubs.DiagramResource;
30 import org.simantics.layer0.Layer0;
31 import org.simantics.modeling.ModelingResources;
32 import org.simantics.modeling.ModelingUtils.CompositeInfo;
33 import org.simantics.modeling.ModelingUtils.DiagramComponentInfo;
34 import org.simantics.structural.stubs.StructuralResource2;
35
36 /**
37  * @author Tuukka Lehtonen
38  */
39 public class CompositeCopyHandler extends DefaultCopyHandler {
40
41     public CompositeCopyHandler(Resource composite) {
42         super(composite);
43     }
44
45     public CompositeCopyHandler(Collection<Resource> composites) {
46         super(composites);
47     }
48
49     @Override
50     protected TransferableGraphConfiguration2 createConfiguration(ReadGraph graph, boolean cut) throws DatabaseException {
51
52         Layer0 L0 = Layer0.getInstance(graph);
53         StructuralResource2 SR = StructuralResource2.getInstance(graph);
54         DiagramResource DIA = DiagramResource.getInstance(graph);
55         ModelingResources MOD = ModelingResources.getInstance(graph);
56
57         Set<Resource> resourceSet = (resources instanceof Set)
58                 ? (Set<Resource>) resources : new HashSet<>(resources);
59         Set<Resource> exclusions = new HashSet<>();
60         Set<Resource> externals = new HashSet<>();
61         List<RootSpec> roots = new ArrayList<>();
62
63         Resource indexRoot = graph.syncRequest(new PossibleIndexRoot(resources.iterator().next()));
64         if(indexRoot == null) throw new DatabaseException("Composite is not part of any index root");
65         String indexRootUri = graph.getURI(indexRoot);
66
67         for(Resource resource : resources) {
68             // Process all connection joins.
69             // This is the only way to access all of them.
70             for (Resource diagram : graph.getObjects(resource, MOD.CompositeToDiagram)) {
71                 for (Resource flag : graph.syncRequest(new ObjectsWithType(diagram, L0.ConsistsOf, DIA.Flag))) {
72                     for (Resource join : graph.getObjects(flag, DIA.FlagIsJoinedBy)) {
73                         // Joins with external references are omitted
74                         for (Resource comp : graph.getObjects(join, SR.JoinsComposite)) {
75                             if (!resourceSet.contains(comp))
76                                 exclusions.add(join);
77                         }
78                         // This code excludes joins with flags to external
79                         // diagrams that are not connected (have no
80                         // configuration for the flag)
81                         for (Resource flag2 : graph.getObjects(join, DIA.JoinsFlag)) {
82                             Resource diagram2 = graph.getPossibleObject(flag2, L0.PartOf);
83                             if (diagram2 != null) {
84                                 Resource comp = graph.getPossibleObject(diagram2, MOD.DiagramToComposite);
85                                 if (!resourceSet.contains(comp))
86                                     exclusions.add(join); 
87                             }
88                         }
89                     }
90                 }
91
92                 // Check all diagram monitor elements.
93                 // Any components referenced that are external to the exported diagrams must be excluded from the export.
94                 // This will leave the monitors without a monitored component but export and import will work anyway.
95                 for (Resource ref : graph.syncRequest(new ObjectsWithType(diagram, L0.ConsistsOf, DIA.Monitor))) {
96                     for (Resource monitoredComponent : graph.getObjects(ref, DIA.HasMonitorComponent)) {
97                         Resource monitoredComponentComposite = graph.getPossibleObject(monitoredComponent, L0.PartOf);
98                         if (monitoredComponentComposite != null && !resourceSet.contains(monitoredComponentComposite)) {
99                             exclusions.add(monitoredComponent);
100                         }
101                     }
102                 }
103             }
104
105             // Leave any diagram monitors out of the export that are contained
106             // by diagrams that are not part of this export, when the monitored
107             // components happen to be a part of the exported composites.
108             for (Resource ref : graph.syncRequest(new ObjectsWithType(resource, L0.ConsistsOf, SR.Component))) {
109                 for (Resource monitor : graph.getObjects(ref, DIA.HasMonitorComponent_Inverse)) {
110                     Resource monitorDiagram = graph.getPossibleObject(monitor, L0.PartOf);
111                     if (monitorDiagram != null) {
112                         Resource monitorComposite = graph.getPossibleObject(monitorDiagram, MOD.DiagramToComposite);
113                         if (monitorComposite != null && !resourceSet.contains(monitorComposite))
114                             exclusions.add(monitor);
115                     }
116                 }
117             }
118
119             // Include resource as root
120             CompositeInfo info = CompositeInfo.fromResource(graph, resource);
121             roots.add(new RootSpec(resource, info.getTGName(), true, typeId(graph, L0, indexRootUri, resource)));
122                 Resource id = graph.getPossibleObject(resource, L0.identifier);
123                 if(id != null) exclusions.add(id);
124             // Include components as roots
125             for(Resource child : graph.sync(new ObjectsWithType(resource, L0.ConsistsOf, SR.Component))) {
126                 DiagramComponentInfo cinfo = DiagramComponentInfo.fromResource(graph, info, child);
127                 id = graph.getPossibleObject(child, L0.identifier);
128                 if(id != null) exclusions.add(id);
129                 roots.add(new RootSpec(child, cinfo.getTGName(info), true, typeId(graph, L0, indexRootUri, child)));
130             }
131         }
132
133         roots.add(new RootSpec(indexRoot, "%model", false));
134
135         TransferableGraphConfiguration2 config = TransferableGraphConfiguration2.createWithNames2(graph, roots, exclusions, true, false);
136         for (Resource external : externals)
137             config.preStatus.put(external, ExtentStatus.EXTERNAL);
138         return config;
139     }
140
141     private static String typeId(ReadGraph graph, Layer0 L0, String indexRootUri, Resource r) throws DatabaseException {
142         Resource type = graph.getPossibleType(r, L0.Entity);
143         if (type == null)
144             return Layer0.URIs.Entity;
145         String typeUri = graph.getPossibleURI(type);
146         if (typeUri == null || !typeUri.startsWith(indexRootUri))
147             return typeUri;
148         return "%model" + typeUri.substring(indexRootUri.length());
149     }
150
151 }