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