Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#13 add preferred language setting to limit the literals being returned #18

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,16 @@ spider.`name_literal@ru`.println('Name literal of Spiderman in Russian: ');
* `value`: the raw value of the literal (usually a String, but it can be different for typed literals - see [Apache Jena typed literals](https://jena.apache.org/documentation/notes/typed-literals.html)).
* `language`: the language tag for the literal (if any).
* `datatypeURI`: the datatype URI for the literal.

### Limiting returned literals to preferred languages

The "Language tag preference" section of the RDF model configuration dialog allows for specifying a comma-separated list of [BCP 47](https://www.ietf.org/rfc/bcp/bcp47.txt) language tags.
If these preferences are set, `x.property` will filter literals, by only returning the values for the first tag with matches, or falling back to the untagged values if no matches are found for any of the mentioned tags.

For instance, if we set the language preferences to `en-gb,en`, filtering `x.property` will work as follows:

* If any `en-gb` literals exist, return only those.
* If any `en` literals exist, return only those.
* Otherwise, return the untagged literals (if any).

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.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.eclipse.core.resources.IFile;
Expand All @@ -33,13 +35,17 @@
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class RDFModelConfigurationDialog extends AbstractModelConfigurationDialog {

Expand Down Expand Up @@ -74,7 +80,7 @@ protected Object getValue(Object element) {
protected void setValue(Object element, Object value) {
((NamespaceMappingTableEntry)element).prefix = String.valueOf(value);
viewer.update(element, null);
validateURLs();
validateForm();
}
}

Expand Down Expand Up @@ -107,7 +113,7 @@ protected Object getValue(Object element) {
protected void setValue(Object element, Object value) {
((NamespaceMappingTableEntry)element).url = String.valueOf(value);
viewer.update(element, null);
validateURLs();
validateForm();
}
}

Expand Down Expand Up @@ -140,7 +146,7 @@ protected Object getValue(Object element) {
protected void setValue(Object element, Object value) {
((URLTableEntry)element).url = String.valueOf(value);
viewer.update(element, null);
validateURLs();
validateForm();
}
}

Expand Down Expand Up @@ -177,6 +183,7 @@ protected void createGroups(Composite control) {
createNameAliasGroup(control);
createRDFUrlsGroup(control);
createNamespaceMappingGroup(control);
createLanguagePreferenceGroup(control);
}

private Composite createNamespaceMappingGroup(Composite parent) {
Expand Down Expand Up @@ -346,6 +353,7 @@ public void widgetSelected(SelectionEvent e) {
urls.remove(it.next());
}
urlList.refresh();
validateForm();
}
}
});
Expand All @@ -357,6 +365,7 @@ public void widgetSelected(SelectionEvent e) {
public void widgetSelected(SelectionEvent e) {
urls.clear();
urlList.refresh();
validateForm();
}
});

Expand All @@ -365,6 +374,30 @@ public void widgetSelected(SelectionEvent e) {
return groupContent;
}


protected Label languagePreferenceLabel;
protected Text languagePreferenceText;

private Composite createLanguagePreferenceGroup(Composite parent) {
final Composite groupContent = DialogUtil.createGroupContainer(parent, "Language tag preference", 1);

languagePreferenceLabel = new Label(groupContent, SWT.NONE);
languagePreferenceLabel.setText("Comma-separated preferred language tags, in descending priority:");

languagePreferenceText = new Text(groupContent, SWT.BORDER);
languagePreferenceText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
languagePreferenceText.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent event) {
validateForm();
}
});

groupContent.layout();
groupContent.pack();
return groupContent;
}

@Override
protected void loadProperties(){
super.loadProperties();
Expand All @@ -389,12 +422,14 @@ protected void loadProperties(){
}
}
}

languagePreferenceText.setText(properties.getProperty(RDFModel.PROPERTY_LANGUAGE_PREFERENCE));

this.urlList.refresh();
this.nsMappingTable.refresh();
validateURLs();
validateForm();
}

@Override
protected void storeProperties(){
super.storeProperties();
Expand All @@ -408,9 +443,27 @@ protected void storeProperties(){
String.join(",", nsMappingEntries.stream()
.map(e -> e.prefix + "=" + e.url)
.collect(Collectors.toList())));

properties.put(RDFModel.PROPERTY_LANGUAGE_PREFERENCE,
languagePreferenceText.getText().replaceAll("\\s", ""));
}

protected void validateURLs() {
protected void validateForm() {
String text = languagePreferenceText.getText().strip();
if (text.length() > 0) {
Set<String> invalidTags = new HashSet<>();
for (String tag : text.split(",")) {
if (!RDFModel.isValidLanguageTag(tag)) {
invalidTags.add(tag);
}
}
if (!invalidTags.isEmpty()) {
setErrorMessage(String.format(
"Invalid tags: %s", String.join(" ", invalidTags)));
return;
}
}

for (URLTableEntry entry : this.urls) {
String errorMessage = validateURL(entry.url);
if (errorMessage != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;

Expand All @@ -38,6 +39,8 @@

public class RDFModel extends CachedModel<RDFModelElement> {

public static final String PROPERTY_LANGUAGE_PREFERENCE = "languagePreference";

public static final String PROPERTY_URIS = "uris";

/**
Expand All @@ -50,6 +53,7 @@ public class RDFModel extends CachedModel<RDFModelElement> {
*/
public static final String PROPERTY_PREFIXES = "prefixes";

protected final List<String> languagePreference = new ArrayList<>();
protected final Map<String, String> customPrefixesMap = new HashMap<>();
protected final List<String> uris = new ArrayList<>();
protected Model model;
Expand Down Expand Up @@ -136,13 +140,16 @@ public void load(StringProperties properties, IRelativePathResolver resolver) th
* EMC drivers (e.g. the EmfModel class).
*/
this.uris.clear();
for (String uri : properties.getProperty(PROPERTY_URIS).split(",")) {
this.uris.add(uri.strip());
String sUris = properties.getProperty(PROPERTY_URIS, "").strip();
if (!sUris.isEmpty()) {
for (String uri : sUris.split(",")) {
this.uris.add(uri.strip());
}
}

this.customPrefixesMap.clear();
String sPrefixes = properties.getProperty(PROPERTY_PREFIXES, "").strip();
if (sPrefixes.length() > 0) {
if (!sPrefixes.isEmpty()) {
for (String sItem : sPrefixes.split(",")) {
int idxEquals = sItem.indexOf('=');
if (idxEquals <= 0 || idxEquals == sItem.length() - 1) {
Expand All @@ -154,6 +161,22 @@ public void load(StringProperties properties, IRelativePathResolver resolver) th
customPrefixesMap.put(sPrefix, sURI);
}
}

this.languagePreference.clear();
String sLanguagePreference = properties.getProperty(PROPERTY_LANGUAGE_PREFERENCE, "").strip();
if (!sLanguagePreference.isEmpty()) {
for (String tag : sLanguagePreference.split(",")) {
tag = tag.strip();
if (isValidLanguageTag(tag)) {
this.languagePreference.add(tag);
} else {
throw new EolModelLoadingException(
new IllegalArgumentException(
String.format("'%s' is not a valid BCP 47 tag", tag)
), this);
}
}
}

load();
}
Expand Down Expand Up @@ -300,6 +323,10 @@ public void setUri(String uri) {
public Map<String, String> getCustomPrefixesMap() {
return this.customPrefixesMap;
}

public List<String> getLanguagePreference() {
return languagePreference;
}

/**
* <p>
Expand Down Expand Up @@ -338,4 +365,10 @@ public String getPrefix(String namespaceURI) {
}
return model.getNsURIPrefix(namespaceURI);
}

// Using Java's Locale class to check that tags conform to bcp47 structure
public static boolean isValidLanguageTag (String bcp47tag) {
boolean isValidBCP47 = !("und".equals(Locale.forLanguageTag(bcp47tag).toLanguageTag()));
return isValidBCP47;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ public static RDFQualifiedName from(String prefix, String nsURI, String localNam
public RDFQualifiedName withLocalName(String newLocalName) {
return new RDFQualifiedName(prefix, namespaceURI, newLocalName, languageTag);
}

public RDFQualifiedName withLanguageTag(String newLanguageTag) {
return new RDFQualifiedName(prefix, namespaceURI, localName, newLanguageTag);
}

@Override
public String toString() {
Expand Down
Loading