1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
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
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.project;
14 import java.util.Collection;
15 import java.util.HashMap;
16 import java.util.HashSet;
20 import org.simantics.databoard.Bindings;
21 import org.simantics.db.ReadGraph;
22 import org.simantics.db.RequestProcessor;
23 import org.simantics.db.Resource;
24 import org.simantics.db.WriteGraph;
25 import org.simantics.db.common.request.Queries;
26 import org.simantics.db.common.utils.NameUtils;
27 import org.simantics.db.exception.DatabaseException;
28 import org.simantics.db.layer0.adapter.impl.EntityRemover;
29 import org.simantics.db.layer0.util.RemoverUtil;
30 import org.simantics.layer0.Layer0;
31 import org.simantics.project.features.IProjectFeature;
32 import org.simantics.project.features.registry.GroupReference;
33 import org.simantics.project.internal.ProjectPolicy;
34 import org.simantics.project.internal.SafeName;
35 import org.simantics.project.ontology.ProjectResource;
38 * Utilities for project life-cycle management and configuration in a Simantics
41 * @author Tuukka Lehtonen
43 public class Projects {
49 * @throws DatabaseException
51 public static String getName(RequestProcessor processor, IProject project) throws DatabaseException {
52 return processor.syncRequest(new SafeName(project.get()));
59 * @throws DatabaseException
61 public static Resource createProject(WriteGraph graph, String name) throws DatabaseException {
62 Resource root = graph.getResource("http://Projects");
64 Layer0 L0 = Layer0.getInstance(graph);
65 ProjectResource PROJ = ProjectResource.getInstance(graph);
67 Resource project = graph.newResource();
68 graph.claim(project, L0.InstanceOf, null, PROJ.Project);
69 graph.claim(project, L0.PartOf, root);
70 graph.claimLiteral(project, L0.HasName, name);
76 * Creates a new project into the database with the specified name and
79 * @param graph writable graph for creating the project
80 * @param name name of the new project
81 * @param features the features to attach to the new project
82 * @return the resource of the new project
83 * @throws DatabaseException
85 public static Resource createProject(WriteGraph graph, String name, Collection<GroupReference> features) throws DatabaseException {
86 // Create the new project instance.
87 Resource project = createProject(graph, name);
88 setProjectInstalledGroups(graph, project, features);
95 * @return map of versionid to feature spec resource
96 * @throws DatabaseException
98 public static Map<String, Resource> getInstalledFeatures(ReadGraph graph, Resource project) throws DatabaseException {
99 ProjectResource PROJ = ProjectResource.getInstance(graph);
101 if (ProjectPolicy.TRACE_PROJECT_MANAGEMENT)
102 System.out.println("Looking for installed groups in project '" + NameUtils.getSafeName(graph, project)+ "'");
104 Map<String, Resource> result = new HashMap<String, Resource>();
105 // Remove previous project feature references
106 for (Resource featureSpec : graph.getObjects(project, PROJ.HasFeature)) {
107 Resource group = graph.getSingleObject(featureSpec, PROJ.HasGroupId);
108 String groupId = graph.getPossibleValue(group, Bindings.STRING);
109 // Re-use existing HasFeature definitions if possible.
110 if (groupId == null) continue;
111 if (ProjectPolicy.TRACE_PROJECT_MANAGEMENT)
112 System.out.println("\t+ found existing feature group definition '" + NameUtils.getSafeName(graph, group) + "'");
113 result.put(groupId, featureSpec);
119 * @param graph write transaction handle
120 * @param project the project to modify
121 * @param features the features
123 * @throws DatabaseException
125 public static Resource setProjectInstalledGroups(WriteGraph graph, Resource project, Collection<GroupReference> groups) throws DatabaseException {
126 if (ProjectPolicy.TRACE_PROJECT_MANAGEMENT)
127 System.out.println("Setting installed groups for project '" + NameUtils.getSafeName(graph, project) + "' to " + groups);
129 Set<String> groupStringsToAdd = new HashSet<String>();
130 for (GroupReference ref : groups)
131 groupStringsToAdd.add(ref.toString());
133 Map<String, Resource> existing = getInstalledFeatures(graph, project);
134 Set<Resource> specsToRemove = new HashSet<Resource>();
136 for (Map.Entry<String, Resource> entry : existing.entrySet()) {
137 // Re-use existing HasFeature definitions if possible.
138 if (groupStringsToAdd.remove(entry.getKey())) {
139 if (ProjectPolicy.TRACE_PROJECT_MANAGEMENT)
140 System.out.println("\t= reusing existing definition: " + entry.getKey());
144 if (ProjectPolicy.TRACE_PROJECT_MANAGEMENT)
145 System.out.println("\t- marking for removal: " + entry.getKey());
146 specsToRemove.add(entry.getValue());
149 for (Resource groupToRemove : specsToRemove) {
150 uninstallGroup(graph, project, groupToRemove);
153 // Install the specified features to the project.
154 for (String groupString : groupStringsToAdd) {
155 installGroup(graph, project, groupString);
162 * @param graph write transaction handle
163 * @param project the project to install the group id to
164 * @param groupId the group id to install
165 * @return the new group resource
166 * @throws DatabaseException
168 public static Resource installGroup(WriteGraph graph, Resource project, String groupId) throws DatabaseException {
169 Layer0 L0 = Layer0.getInstance(graph);
170 ProjectResource PROJ = ProjectResource.getInstance(graph);
172 if (ProjectPolicy.TRACE_PROJECT_MANAGEMENT)
173 System.out.println("+ Installing group '" + groupId+ "' to project '" + NameUtils.getSafeName(graph, project) + "'");
175 Resource groupIdRes = graph.newResource();
176 graph.claim(groupIdRes, L0.InstanceOf, null, L0.String);
177 graph.claimValue(groupIdRes, groupId);
179 Resource isRequiredRes = graph.newResource();
180 graph.claim(isRequiredRes, L0.InstanceOf, null, L0.Boolean);
181 graph.claimValue(isRequiredRes, true);
183 Resource featureSpec = graph.newResource();
184 graph.claim(featureSpec, L0.InstanceOf, null, PROJ.FeatureSpec);
185 graph.claim(project, PROJ.HasFeature, featureSpec);
186 graph.claim(featureSpec, PROJ.HasGroupId, groupIdRes);
187 graph.claim(featureSpec, PROJ.IsRequired, isRequiredRes);
193 * @param graph write transaction handle
194 * @param project the project to uninstall the group id from
195 * @param groupId the group id to uninstall
196 * @return <code>true</code> if successfully uninstalled, <code>false</code>
197 * if group id not found
198 * @throws DatabaseException
200 public static boolean uninstallGroup(WriteGraph graph, Resource project, String groupId) throws DatabaseException {
201 ProjectResource PROJ = ProjectResource.getInstance(graph);
203 if (ProjectPolicy.TRACE_PROJECT_MANAGEMENT)
204 System.out.println("- Uninstalling group '" + groupId+ "' from project '" + NameUtils.getSafeName(graph, project) + "'");
206 for (Resource featureSpec : graph.getObjects(project, PROJ.HasFeature)) {
207 Resource group = graph.getSingleObject(featureSpec, PROJ.HasGroupId);
208 String existingGroup = graph.getPossibleValue(group, Bindings.STRING);
209 // Re-use existing HasFeature definitions if possible.
210 if (groupId.equals(existingGroup)) {
211 if (ProjectPolicy.TRACE_PROJECT_MANAGEMENT)
212 System.out.println("\t - found it, removing");
213 graph.deny(featureSpec, PROJ.HasGroupId, group);
214 EntityRemover.remove(graph, group, false);
217 graph.deny(project, PROJ.HasFeature, featureSpec);
218 EntityRemover.remove(graph, featureSpec, false);
225 * @param graph write transaction handle
226 * @param project the project to uninstall the group id from
227 * @param featureSpec the feature specification to uninstall
228 * @return <code>true</code> if successfully uninstalled, <code>false</code>
229 * if group id not found
230 * @throws DatabaseException
232 public static boolean uninstallGroup(WriteGraph graph, Resource project, Resource featureSpec) throws DatabaseException {
233 ProjectResource PROJ = ProjectResource.getInstance(graph);
235 if (ProjectPolicy.TRACE_PROJECT_MANAGEMENT)
236 System.out.println("- Uninstalling group '" + NameUtils.getSafeName(graph, featureSpec) + "' from project '" + NameUtils.getSafeName(graph, project) + "'");
238 Resource groupId = graph.getPossibleObject(featureSpec, PROJ.HasGroupId);
240 graph.deny(featureSpec, PROJ.HasGroupId, groupId);
241 EntityRemover.remove(graph, groupId, false);
245 if (graph.hasStatement(project, PROJ.HasFeature, featureSpec)) {
246 graph.deny(project, PROJ.HasFeature, featureSpec);
247 EntityRemover.remove(graph, featureSpec, false);
255 * Tries to load the specified project from a database.
258 * After this method completes, the project knows all its project features
259 * (see {@link IProjectFeature}). The list of features should be available
260 * through {@link IProject#getFeatures()}.
263 * @param graph readable graph for loading the project
264 * @param project the project resource to load
265 * @param activate <code>true</code> to invoke <code>onActivated</code> for
266 * all {@link IProjectLifecycle}'s of this project.
267 * @return the loaded project.
269 public static IProject loadProject(RequestProcessor processor, Resource project) throws DatabaseException {
270 IProject p = processor.syncRequest( Queries.adapt(project, IProject.class, false, true) );
275 * Destroys the specified project from the database.
277 * @param g writable graph for deleting the project
278 * @param project the project to destroy
279 * @throws DatabaseException
281 public static void deleteProject(WriteGraph g, Resource project) throws DatabaseException {
282 // NOTE: this will throw ServiceException if adapters are not initialized!
283 RemoverUtil.remove(g, project);