Skip to content

Commit

Permalink
Add support for platform: URLs (fixes #12)
Browse files Browse the repository at this point in the history
This commit creates a new EclipseRDFModel subclass which preprocesses platform:/ URLs into standard file:/ URLs that Jena can work with as usual. It also updates the Eclipse UI to make use of that subclass by default.

---------

Co-authored-by: Antonio Garcia-Dominguez <[email protected]>
  • Loading branch information
OwenR-York and agarciadom authored Jan 29, 2025
1 parent 698f834 commit e9ea6c7
Show file tree
Hide file tree
Showing 14 changed files with 445 additions and 8 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,10 @@ For instance, if we set the language preferences to `en-gb,en`, filtering `x.pro

Language preferences do not apply if an explicit language tag is used: `x.property@en` will always get the `en`-tagged literals, and `x.property@` will always get the untagged literals.

### Platform URL support

Data and schema models can be loaded using `platform:/` URLs when using the driver in an Eclipse enviroment. All `platform:/` URLs are converted to `file:/` URLs before being passed to Jena.

### Data models, schema models and reasoners

RDF models are loaded as Ontology Resource Models with Jena's default OWL reasoner.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ Bundle-ManifestVersion: 2
Bundle-Name: Developer Tools for Epsilon Model Connectivity RDF driver
Bundle-SymbolicName: org.eclipse.epsilon.emc.rdf.dt;singleton:=true
Bundle-Version: 1.0.0.qualifier
Export-Package: org.eclipse.epsilon.emc.rdf.dt
Require-Bundle: org.eclipse.epsilon.emc.rdf;bundle-version="1.0.0",
org.eclipse.epsilon.common.dt;bundle-version="2.1.0"
Bundle-Vendor: University of York
Expand Down
2 changes: 1 addition & 1 deletion bundles/org.eclipse.epsilon.emc.rdf.dt/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<extension
point="org.eclipse.epsilon.common.dt.modelType">
<modelType
class="org.eclipse.epsilon.emc.rdf.RDFModel"
class="org.eclipse.epsilon.emc.rdf.dt.EclipseRDFModel"
dialog="org.eclipse.epsilon.emc.rdf.dt.RDFModelConfigurationDialog"
icon="icons/sw-cube.png"
label="RDF Model"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/********************************************************************************
* Copyright (c) 2024 University of York
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Antonio Garcia-Dominguez - initial API and implementation
********************************************************************************/
package org.eclipse.epsilon.emc.rdf.dt;

import java.net.URL;
import java.util.List;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.epsilon.emc.rdf.RDFModel;
import org.eclipse.epsilon.eol.exceptions.models.EolModelLoadingException;

public class EclipseRDFModel extends RDFModel {

@Override
protected void loadModel() throws EolModelLoadingException {
// Change any platform:/ URLs to file:/ URLs in these lists...
processEclipsePlatformUrlsToFileUrls(schemaURIs);
processEclipsePlatformUrlsToFileUrls(dataURIs);

// Call the RDFModel load as normal, no platform URLs are passed to Jena
super.loadModel();
}

// Pushes a list of URLs through a process to turn any Platform:/ into File:/
private void processEclipsePlatformUrlsToFileUrls(List<String> urlList) throws EolModelLoadingException {
for (int i = 0; i < urlList.size(); i++) {
urlList.set(i, processPlatformURLtoFileUrl(urlList.get(i)));
}
}

// A File:/ URL or relative path starting '/' or '.' is unchanged by this process, Platform:/ URLs become File:/ URLs
// Attempts to resolve a String to a URI and then URL, then gets the File:/ URL and returns it
private String processPlatformURLtoFileUrl(String urlString) throws EolModelLoadingException {
if (!urlString.startsWith("platform:")) {
return urlString;
}

try {
URL url = new URL(urlString);
URL fileSystemPathUrl = FileLocator.toFileURL(url);
return fileSystemPathUrl.toString();
} catch (Exception ex) {
ex.printStackTrace();
throw new EolModelLoadingException(ex, this);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -155,11 +155,14 @@ protected class NamespaceMappingTableEntry {
public String prefix, url;
}

private String getIFilePlatformAsUrlString(IFile file) {
return "platform:/resource" + file.getFullPath().toPortableString();
}

protected class URLTableEntry {
public URLTableEntry(String url) {
this.url = url;
}

public String url;
}

Expand Down Expand Up @@ -317,11 +320,11 @@ public void widgetSelected(SelectionEvent e) {
addFromWorkspaceButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {

IFile file = BrowseWorkspaceUtil.browseFile(getShell(),
"Browse workspace", "Select file with RDF content", "*.rdf", null);

"Browse workspace", "Select file with RDF content", "*.rdf", null);
if (file != null) {
dataModelUrls.add(new URLTableEntry(file.getLocationURI().toString()));
dataModelUrls.add(new URLTableEntry(getIFilePlatformAsUrlString(file)));
dataModelUrlListViewer.refresh();
}
}
Expand Down Expand Up @@ -426,7 +429,7 @@ public void widgetSelected(SelectionEvent e) {
"Browse workspace", "Select file with RDF content", "*.rdf", null);

if (file != null) {
schemaModelUrls.add(new URLTableEntry(file.getLocationURI().toString()));
schemaModelUrls.add(new URLTableEntry(getIFilePlatformAsUrlString(file)));
schemaModelUrlListViewer.refresh();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<booleanAttribute key="fine_grained_profiling" value="false"/>
<stringAttribute key="implementation_name" value="Parallel"/>
<listAttribute key="models">
<listEntry value="aliases=aModel&#10;languagePreference=&#10;name=Model&#10;prefixes=&#10;schemaUris=file\:/home/hmz514/git/emc-rdf/examples/org.eclipse.epsilon.examples.emc.rdf.OWLdemodata/owlDemoSchema.ttl&#10;type=RDF&#10;uris=file\:/home/hmz514/git/emc-rdf/examples/org.eclipse.epsilon.examples.emc.rdf.OWLdemodata/owlDemoData.ttl"/>
<listEntry value="uris=platform\:/resource/org.eclipse.epsilon.examples.emc.rdf.OWLdata/owlDemoData.ttl&#10;languagePreference=&#10;prefixes=&#10;aliases=&#10;name=Model&#10;schemaUris=platform\:/resource/org.eclipse.epsilon.examples.emc.rdf.OWLdata/owlDemoSchema.ttl&#10;type=RDF"/>
</listAttribute>
<booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
<intAttribute key="parallelism" value="7"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<launchConfiguration type="org.epsilon.eol.eclipse.dt.launching.EolLaunchConfigurationDelegate">
<stringAttribute key="implementation_name" value="Parallel"/>
<listAttribute key="models">
<listEntry value="aliases=&#10;lanuguagePreference=fr&#10;name=Model&#10;prefixes=&#10;type=RDF&#10;uris=file\:/home/hmz514/git/emc-rdf/examples/org.eclipse.epsilon.examples.emc.rdf.turtles/foaf.rdf,file\:/home/hmz514/git/emc-rdf/examples/org.eclipse.epsilon.examples.emc.rdf.turtles/spiderman.ttl"/>
<listEntry value="uris=platform\:/resource/org.eclipse.epsilon.examples.emc.rdf.turtles/foaf.rdf,platform\:/resource/org.eclipse.epsilon.examples.emc.rdf.turtles/spiderman.ttl&#10;languagePreference=&#10;prefixes=&#10;aliases=&#10;name=Model&#10;schemaUris=&#10;type=RDF"/>
</listAttribute>
<booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
<intAttribute key="parallelism" value="7"/>
Expand Down
11 changes: 11 additions & 0 deletions tests/org.eclipse.epsilon.emc.rdf.dt.tests/.classpath
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src">
<attributes>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="bin"/>
</classpath>
28 changes: 28 additions & 0 deletions tests/org.eclipse.epsilon.emc.rdf.dt.tests/.project
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.epsilon.emc.rdf.dt.tests</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
org.eclipse.jdt.core.compiler.compliance=17
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.release=enabled
org.eclipse.jdt.core.compiler.source=17
14 changes: 14 additions & 0 deletions tests/org.eclipse.epsilon.emc.rdf.dt.tests/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Tests for EMC RDF developer tools
Bundle-SymbolicName: org.eclipse.epsilon.emc.rdf.dt.tests
Bundle-Version: 1.0.0.qualifier
Require-Bundle: org.eclipse.epsilon.emc.rdf,
org.eclipse.epsilon.emc.rdf.dt,
org.eclipse.equinox.registry;bundle-version="3.0.0",
org.junit;bundle-version="[4.0.0,5.0.0)",
org.eclipse.epsilon.eol.engine;bundle-version="2.0.0",
org.eclipse.core.resources;bundle-version="3.0.0"
Bundle-Vendor: University of York
Automatic-Module-Name: org.eclipse.epsilon.emc.rdf.dt.tests
Bundle-RequiredExecutionEnvironment: JavaSE-17
4 changes: 4 additions & 0 deletions tests/org.eclipse.epsilon.emc.rdf.dt.tests/build.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/********************************************************************************
* Copyright (c) 2024 University of York
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Antonio Garcia-Dominguez - initial API and implementation
********************************************************************************/
package org.eclipse.epsilon.emc.rdf.dt.tests;

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Path;
import org.junit.After;
import org.junit.Before;
public class EclipseProjectEnvTest {

/**
* <p>
* Base class for tests requiring an Eclipse IDE project and workbench environment.
* </p>
*
* <p>
* Note: all tests based on this class must run as JUnit Plug-In tests, not as
* regular tests, and the ui.workbench product (or Headless) needs to be run. We need a
* working, open workbench for these tests.
* </p>
*/

private final int FILESYSTEM_SYNC_TIMEOUT_SECONDS = 10;

private final String projectUrl;

private IProject testProject;

/**
* Creates a new project with this URL
*
* @param projectUrl
* Project URL to use for a project resource in Eclipse IDE Workbench that the test will use
*/
public EclipseProjectEnvTest(String projectUrl) {
this.projectUrl = projectUrl;
}

@Before
public void createTestProject() throws Exception {
final IWorkspace workspace = ResourcesPlugin.getWorkspace();
final IWorkspaceRoot root = workspace.getRoot();

testProject = root.getProject(projectUrl);
if (testProject.exists()) {
deleteTestProject();
}
testProject.create(null);
testProject.open(null);
}

@After
public void deleteTestProject() throws Exception {
testProject.delete(true, true, null);

int count = 0;
while (!testProject.isSynchronized(1)) {
count = checkTimeOut(count, FILESYSTEM_SYNC_TIMEOUT_SECONDS,"Waiting for delete sync... ");
}
}

public void copyIntoProject(String from, String to) throws Exception {
IFile destFile=null;
try (InputStream source = new FileInputStream(from)) {
destFile = testProject.getFile(new Path(to));
createParentFolders(destFile);
destFile.create(source, false, null);
}
if (null != destFile) {
int count = 0;
while (!destFile.isSynchronized(1)) {
count = checkTimeOut(count, FILESYSTEM_SYNC_TIMEOUT_SECONDS,"Waiting for file sync");
}
}
}

private static void createParentFolders(IResource res) throws Exception {
final IContainer parent = res.getParent();
if (parent instanceof IFolder) {
createParentFolders(parent);
}
if (res instanceof IFolder && !res.exists()) {
((IFolder) res).create(false, true, null);
}
}

// Delays 1 second, set limit to X seconds you want to wait
private int checkTimeOut(int current, int limit, String errorLabel) throws Exception {
System.out.println(" - " + errorLabel + " Time out: " + current + "/" + limit );
if (current >= limit)
{
//System.err.println("Check time out error: " + errorLabel);
throw new Exception("Check time out error: " + errorLabel);
}
delaySeconds(1);
return ++current;
}

private void delaySeconds(int seconds) {
try {
TimeUnit.SECONDS.sleep(seconds);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
}
}

public String getProjectUrl() {
return projectUrl;
}

public String getTestProjectURIString() {
return testProject.getLocationURI().toString();
}

public IProject getTestProject() {
return testProject;
}
}
Loading

0 comments on commit e9ea6c7

Please sign in to comment.