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.features;
15 import java.net.URISyntaxException;
16 import java.util.ArrayList;
17 import java.util.Collection;
19 import org.eclipse.core.runtime.CoreException;
20 import org.eclipse.core.runtime.IConfigurationElement;
21 import org.eclipse.core.runtime.IExecutableExtension;
22 import org.eclipse.core.runtime.IStatus;
23 import org.eclipse.core.runtime.Status;
24 import org.simantics.db.Resource;
25 import org.simantics.db.Session;
26 import org.simantics.db.VirtualGraph;
27 import org.simantics.db.WriteGraph;
28 import org.simantics.db.common.CommentMetadata;
29 import org.simantics.db.common.request.WriteRequest;
30 import org.simantics.db.common.utils.NameUtils;
31 import org.simantics.db.exception.AssumptionException;
32 import org.simantics.db.exception.DatabaseException;
33 import org.simantics.db.exception.ResourceNotFoundException;
34 import org.simantics.db.service.VirtualGraphSupport;
35 import org.simantics.layer0.Layer0;
36 import org.simantics.project.exception.ProjectException;
37 import org.simantics.project.ontology.ProjectResource;
38 import org.simantics.scl.reflection.OntologyVersions;
41 * A project feature for validating that a set of namespaces (URIs) are
42 * reachable in the database for which this feature is configured.
44 * The URIs are described as class arguments in the extension class spec (after
47 * @author Tuukka Lehtonen
49 public class DependencyValidationFeature extends AbstractProjectFeature implements IExecutableExtension {
51 private String virtualGraphId;
52 private String[] uris = {};
54 public DependencyValidationFeature() {
57 public DependencyValidationFeature(String virtualGraphId, String[] uris) {
58 this.virtualGraphId = virtualGraphId;
63 public void setInitializationData(IConfigurationElement config, String propertyName, Object data)
64 throws CoreException {
65 if (data instanceof String) {
66 // Expecting comma-separated list of URIs in the argument.
67 String[] uris = ((String) data).split(",");
68 if (uris.length > 0) {
69 for(int i=0;i<uris.length;i++) uris[i] = OntologyVersions.getInstance().currentVersion(uris[i]);
70 // Validate the input data to contain valid URIs
71 for (String uri : uris) {
74 } catch (URISyntaxException e) {
75 throw new CoreException(new Status(IStatus.ERROR, config.getContributor().getName(), "extension configuration element executable extension attribute '" + propertyName + "' argument contains invalid URIs. See cause for details.", e));
85 public void configure() throws ProjectException {
87 Session s = getSession();
88 VirtualGraph vg = null;
89 if (virtualGraphId != null) {
90 VirtualGraphSupport support = s.getService(VirtualGraphSupport.class);
91 vg = support.getWorkspacePersistent(virtualGraphId);
93 getSession().syncRequest(new WriteRequest(vg) {
95 public void perform(WriteGraph graph) throws DatabaseException {
97 graph.addMetadata(graph.getMetadata(CommentMetadata.class).add("Configured by Dependency Validation Feature."));
100 } catch (DatabaseException e) {
101 throw new ProjectException(e.getMessage(), e);
105 protected void configure(WriteGraph graph) throws DatabaseException {
106 Collection<String> nss = new ArrayList<String>();
107 Collection<String> notFound = new ArrayList<String>();
109 Resource project = getProject().get();
110 String projectName = NameUtils.getSafeName(graph, project);
112 ProjectResource PROJ = ProjectResource.getInstance(graph);
114 ArrayList<Resource> resourcesToLinkToProject = new ArrayList<Resource>();
116 for (String uri : uris) {
117 // This will fail if the extension-specified URI does not exist
118 Resource namespaceRequirement = null;
120 namespaceRequirement = graph.getResource(uri);
121 resourcesToLinkToProject.add(namespaceRequirement);
122 } catch (ResourceNotFoundException e) {
127 for (Resource nsp : graph.getObjects(namespaceRequirement, PROJ.RequiresNamespace)) {
128 String ns = graph.getValue(nsp);
132 for (String ns : nss) {
134 // This will fail if the namespace is not found.
135 graph.getResource(ns);
136 } catch (ResourceNotFoundException e) {
142 if (!notFound.isEmpty()) {
143 StringBuilder sb = new StringBuilder();
144 sb.append("Failed to locate the following namespaces required by project '");
145 sb.append(projectName);
147 for (String nf : notFound) {
152 throw new AssumptionException(sb.toString());
155 // Ensure that the namespace requirements are linked to the project to
156 // make them discoverable by database queries.
157 linkTo(graph, project, resourcesToLinkToProject);
160 protected void linkTo(WriteGraph graph, Resource target, ArrayList<Resource> resourcesToLink) throws DatabaseException {
161 Layer0 L0 = Layer0.getInstance(graph);
162 for (Resource resource : resourcesToLink) {
163 if (!graph.hasStatement(target, L0.IsLinkedTo, resource))
164 graph.claim(target, L0.IsLinkedTo, resource);
169 public void deconfigure() throws ProjectException {