]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.project/src/org/simantics/project/Projects.java
Merge commit '728147df5d63a3333daff3d8c0e9bfd4f5597e3a'
[simantics/platform.git] / bundles / org.simantics.project / src / org / simantics / project / Projects.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.project;\r
13 \r
14 import java.util.Collection;\r
15 import java.util.HashMap;\r
16 import java.util.HashSet;\r
17 import java.util.Map;\r
18 import java.util.Set;\r
19 \r
20 import org.simantics.databoard.Bindings;\r
21 import org.simantics.db.ReadGraph;\r
22 import org.simantics.db.RequestProcessor;\r
23 import org.simantics.db.Resource;\r
24 import org.simantics.db.WriteGraph;\r
25 import org.simantics.db.common.request.Queries;\r
26 import org.simantics.db.common.utils.NameUtils;\r
27 import org.simantics.db.exception.DatabaseException;\r
28 import org.simantics.db.layer0.adapter.impl.EntityRemover;\r
29 import org.simantics.db.layer0.util.RemoverUtil;\r
30 import org.simantics.layer0.Layer0;\r
31 import org.simantics.project.features.IProjectFeature;\r
32 import org.simantics.project.features.registry.GroupReference;\r
33 import org.simantics.project.internal.ProjectPolicy;\r
34 import org.simantics.project.internal.SafeName;\r
35 import org.simantics.project.ontology.ProjectResource;\r
36 \r
37 /**\r
38  * Utilities for project life-cycle management and configuration in a Simantics\r
39  * graph database.\r
40  * \r
41  * @author Tuukka Lehtonen\r
42  */\r
43 public class Projects {\r
44 \r
45     /**\r
46      * @param processor\r
47      * @param project\r
48      * @return\r
49      * @throws DatabaseException\r
50      */\r
51     public static String getName(RequestProcessor processor, IProject project) throws DatabaseException {\r
52         return processor.syncRequest(new SafeName(project.get()));\r
53     }\r
54 \r
55     /**\r
56      * @param graph\r
57      * @param name\r
58      * @return\r
59      * @throws DatabaseException\r
60      */\r
61     public static Resource createProject(WriteGraph graph, String name) throws DatabaseException {\r
62         Resource root = graph.getResource("http://Projects");\r
63 \r
64         Layer0 L0 = Layer0.getInstance(graph);\r
65         ProjectResource PROJ = ProjectResource.getInstance(graph);\r
66 \r
67         Resource project = graph.newResource();\r
68         graph.claim(project, L0.InstanceOf, null, PROJ.Project);\r
69         graph.claim(project, L0.PartOf, root);\r
70         graph.claimLiteral(project, L0.HasName, name);\r
71 \r
72         return project;\r
73     }\r
74 \r
75     /**\r
76      * Creates a new project into the database with the specified name and\r
77      * specified features.\r
78      * \r
79      * @param graph writable graph for creating the project\r
80      * @param name name of the new project\r
81      * @param features the features to attach to the new project\r
82      * @return the resource of the new project\r
83      * @throws DatabaseException\r
84      */\r
85     public static Resource createProject(WriteGraph graph, String name, Collection<GroupReference> features) throws DatabaseException {\r
86         // Create the new project instance.\r
87         Resource project = createProject(graph, name);\r
88         setProjectInstalledGroups(graph, project, features);\r
89         return project;\r
90     }\r
91 \r
92     /**\r
93      * @param graph\r
94      * @param project\r
95      * @return map of versionid to feature spec resource\r
96      * @throws DatabaseException\r
97      */\r
98     public static Map<String, Resource> getInstalledFeatures(ReadGraph graph, Resource project) throws DatabaseException {\r
99         ProjectResource PROJ = ProjectResource.getInstance(graph);\r
100 \r
101         if (ProjectPolicy.TRACE_PROJECT_MANAGEMENT)\r
102             System.out.println("Looking for installed groups in project '" + NameUtils.getSafeName(graph, project)+ "'");\r
103 \r
104         Map<String, Resource> result = new HashMap<String, Resource>();\r
105         // Remove previous project feature references\r
106         for (Resource featureSpec : graph.getObjects(project, PROJ.HasFeature)) {\r
107                 Resource group = graph.getSingleObject(featureSpec, PROJ.HasGroupId);\r
108             String groupId = graph.getPossibleValue(group, Bindings.STRING);\r
109             // Re-use existing HasFeature definitions if possible.\r
110             if (groupId == null) continue;\r
111             if (ProjectPolicy.TRACE_PROJECT_MANAGEMENT)\r
112                 System.out.println("\t+ found existing feature group definition '" + NameUtils.getSafeName(graph, group) + "'");\r
113             result.put(groupId, featureSpec);            \r
114         }\r
115         return result;\r
116     }\r
117 \r
118     /**\r
119      * @param graph write transaction handle\r
120      * @param project the project to modify\r
121      * @param features the features\r
122      * @return\r
123      * @throws DatabaseException\r
124      */\r
125     public static Resource setProjectInstalledGroups(WriteGraph graph, Resource project, Collection<GroupReference> groups) throws DatabaseException {\r
126         if (ProjectPolicy.TRACE_PROJECT_MANAGEMENT)\r
127             System.out.println("Setting installed groups for project '" + NameUtils.getSafeName(graph, project) + "' to " + groups);\r
128 \r
129         Set<String> groupStringsToAdd = new HashSet<String>();\r
130         for (GroupReference ref : groups)\r
131             groupStringsToAdd.add(ref.toString());\r
132 \r
133         Map<String, Resource> existing = getInstalledFeatures(graph, project);\r
134         Set<Resource> specsToRemove = new HashSet<Resource>();\r
135 \r
136         for (Map.Entry<String, Resource> entry : existing.entrySet()) {\r
137             // Re-use existing HasFeature definitions if possible.\r
138             if (groupStringsToAdd.remove(entry.getKey())) {\r
139                 if (ProjectPolicy.TRACE_PROJECT_MANAGEMENT)\r
140                     System.out.println("\t= reusing existing definition: " + entry.getKey());\r
141                 continue;\r
142             }\r
143 \r
144             if (ProjectPolicy.TRACE_PROJECT_MANAGEMENT)\r
145                 System.out.println("\t- marking for removal: " + entry.getKey());\r
146             specsToRemove.add(entry.getValue());\r
147         }\r
148 \r
149         for (Resource groupToRemove : specsToRemove) {\r
150             uninstallGroup(graph, project, groupToRemove);\r
151         }\r
152 \r
153         // Install the specified features to the project.\r
154         for (String groupString : groupStringsToAdd) {\r
155             installGroup(graph, project, groupString);\r
156         }\r
157 \r
158         return project;\r
159     }\r
160 \r
161     /**\r
162      * @param graph write transaction handle\r
163      * @param project the project to install the group id to\r
164      * @param groupId the group id to install\r
165      * @return the new group resource\r
166      * @throws DatabaseException\r
167      */\r
168     public static Resource installGroup(WriteGraph graph, Resource project, String groupId) throws DatabaseException {\r
169         Layer0 L0 = Layer0.getInstance(graph);\r
170         ProjectResource PROJ = ProjectResource.getInstance(graph);\r
171 \r
172         if (ProjectPolicy.TRACE_PROJECT_MANAGEMENT)\r
173             System.out.println("+ Installing group '" + groupId+ "' to project '" + NameUtils.getSafeName(graph, project) + "'");\r
174 \r
175         Resource groupIdRes = graph.newResource();\r
176         graph.claim(groupIdRes, L0.InstanceOf, null, L0.String);\r
177         graph.claimValue(groupIdRes, groupId);\r
178 \r
179         Resource isRequiredRes = graph.newResource();\r
180         graph.claim(isRequiredRes, L0.InstanceOf, null, L0.Boolean);\r
181         graph.claimValue(isRequiredRes, true);\r
182 \r
183         Resource featureSpec = graph.newResource();\r
184         graph.claim(featureSpec, L0.InstanceOf, null, PROJ.FeatureSpec);\r
185         graph.claim(project, PROJ.HasFeature, featureSpec);\r
186         graph.claim(featureSpec, PROJ.HasGroupId, groupIdRes);\r
187         graph.claim(featureSpec, PROJ.IsRequired, isRequiredRes);\r
188 \r
189         return groupIdRes;\r
190     }\r
191 \r
192     /**\r
193      * @param graph write transaction handle\r
194      * @param project the project to uninstall the group id from\r
195      * @param groupId the group id to uninstall\r
196      * @return <code>true</code> if successfully uninstalled, <code>false</code>\r
197      *         if group id not found\r
198      * @throws DatabaseException\r
199      */\r
200     public static boolean uninstallGroup(WriteGraph graph, Resource project, String groupId) throws DatabaseException {\r
201         ProjectResource PROJ = ProjectResource.getInstance(graph);\r
202 \r
203         if (ProjectPolicy.TRACE_PROJECT_MANAGEMENT)\r
204             System.out.println("- Uninstalling group '" + groupId+ "' from project '" + NameUtils.getSafeName(graph, project) + "'");\r
205 \r
206         for (Resource featureSpec : graph.getObjects(project, PROJ.HasFeature)) {\r
207                 Resource group = graph.getSingleObject(featureSpec, PROJ.HasGroupId); \r
208                 String existingGroup = graph.getPossibleValue(group, Bindings.STRING);\r
209             // Re-use existing HasFeature definitions if possible.\r
210             if (groupId.equals(existingGroup)) {\r
211                 if (ProjectPolicy.TRACE_PROJECT_MANAGEMENT)\r
212                     System.out.println("\t - found it, removing");\r
213                 graph.deny(featureSpec, PROJ.HasGroupId, group);\r
214                 EntityRemover.remove(graph, group, false);\r
215                 return true;\r
216             }\r
217             graph.deny(project, PROJ.HasFeature, featureSpec);\r
218             EntityRemover.remove(graph, featureSpec, false);\r
219         }\r
220 \r
221         return false;\r
222     }\r
223 \r
224     /**\r
225      * @param graph write transaction handle\r
226      * @param project the project to uninstall the group id from\r
227      * @param featureSpec the feature specification to uninstall\r
228      * @return <code>true</code> if successfully uninstalled, <code>false</code>\r
229      *         if group id not found\r
230      * @throws DatabaseException\r
231      */\r
232     public static boolean uninstallGroup(WriteGraph graph, Resource project, Resource featureSpec) throws DatabaseException {\r
233         ProjectResource PROJ = ProjectResource.getInstance(graph);\r
234 \r
235         if (ProjectPolicy.TRACE_PROJECT_MANAGEMENT)\r
236             System.out.println("- Uninstalling group '" + NameUtils.getSafeName(graph, featureSpec) + "' from project '" + NameUtils.getSafeName(graph, project) + "'");\r
237 \r
238         Resource groupId = graph.getPossibleObject(featureSpec, PROJ.HasGroupId);\r
239         if (groupId!=null) {\r
240             graph.deny(featureSpec, PROJ.HasGroupId, groupId);\r
241             EntityRemover.remove(graph, groupId, false);\r
242             return true;\r
243         }\r
244         \r
245         if (graph.hasStatement(project, PROJ.HasFeature, featureSpec)) {\r
246             graph.deny(project, PROJ.HasFeature, featureSpec);\r
247             EntityRemover.remove(graph, featureSpec, false);\r
248             return true;\r
249         }\r
250         \r
251         return false;\r
252     }\r
253 \r
254     /**\r
255      * Tries to load the specified project from a database.\r
256      * \r
257      * <p>\r
258      * After this method completes, the project knows all its project features\r
259      * (see {@link IProjectFeature}). The list of features should be available\r
260      * through {@link IProject#getFeatures()}.\r
261      * </p>\r
262      * \r
263      * @param graph readable graph for loading the project\r
264      * @param project the project resource to load\r
265      * @param activate <code>true</code> to invoke <code>onActivated</code> for\r
266      *        all {@link IProjectLifecycle}'s of this project.\r
267      * @return the loaded project.\r
268      */\r
269     public static IProject loadProject(RequestProcessor processor, Resource project) throws DatabaseException {\r
270         IProject p = processor.syncRequest( Queries.adapt(project, IProject.class, false, true) );\r
271         return p;\r
272     }\r
273 \r
274     /**\r
275      * Destroys the specified project from the database.\r
276      * \r
277      * @param g writable graph for deleting the project\r
278      * @param project the project to destroy\r
279      * @throws DatabaseException\r
280      */\r
281     public static void deleteProject(WriteGraph g, Resource project) throws DatabaseException {\r
282         // NOTE: this will throw ServiceException if adapters are not initialized!\r
283         RemoverUtil.remove(g, project);\r
284     }\r
285 \r
286 }\r