Skip to content

Commit 13a2d43

Browse files
committed
Ensure longest namespace match is used. Disallow prefixes that are substrings of OBO namespace.
1 parent 57298d7 commit 13a2d43

File tree

2 files changed

+176
-1
lines changed

2 files changed

+176
-1
lines changed
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
package org.obolibrary.obo2owl;
2+
3+
import org.semanticweb.owlapi.model.IRI;
4+
import org.semanticweb.owlapi.model.OWLRuntimeException;
5+
import org.semanticweb.owlapi.model.PrefixManager;
6+
import org.semanticweb.owlapi.util.StringComparator;
7+
8+
import javax.annotation.Nonnull;
9+
import javax.annotation.Nullable;
10+
import java.util.*;
11+
12+
public class OBOFormatPrefixManager implements PrefixManager {
13+
14+
private final String OBO_NS = "http://purl.obolibrary.org/obo/";
15+
16+
@Nonnull
17+
private StringComparator comparator = new StringComparator() {
18+
19+
final Comparator<String> comparer = Comparator.comparing(s -> -s.length());
20+
21+
@Override
22+
public int compare(String o1, String o2) {
23+
return comparer.compare(o1, o2);
24+
}
25+
26+
};
27+
28+
@Nonnull
29+
private final TreeMap<String, String> nsToPrefix;
30+
@Nonnull
31+
private final TreeMap<String, String> prefixToNS;
32+
33+
public OBOFormatPrefixManager(@Nullable PrefixManager pm) {
34+
prefixToNS = new TreeMap<>(comparator);
35+
nsToPrefix = new TreeMap<>(comparator);
36+
if (pm != null) {
37+
copyPrefixesFrom(pm);
38+
}
39+
}
40+
41+
@Nonnull
42+
@Override
43+
public StringComparator getPrefixComparator() {
44+
return this.comparator;
45+
}
46+
47+
@Override
48+
public void setPrefixComparator(@Nonnull StringComparator comparator) {
49+
this.comparator = comparator;
50+
}
51+
52+
@Nullable
53+
@Override
54+
public String getDefaultPrefix() {
55+
return null;
56+
}
57+
58+
@Override
59+
public boolean containsPrefixMapping(@Nonnull String prefixName) {
60+
return prefixToNS.containsKey(prefixName);
61+
}
62+
63+
@Nullable
64+
@Override
65+
public String getPrefix(@Nonnull String prefixName) {
66+
return prefixToNS.get(prefixName);
67+
}
68+
69+
@Nonnull
70+
@Override
71+
public Map<String, String> getPrefixName2PrefixMap() {
72+
return Collections.unmodifiableMap(prefixToNS);
73+
}
74+
75+
@Nonnull
76+
@Override
77+
public IRI getIRI(@Nonnull String prefixIRI) {
78+
if (prefixIRI.startsWith("<")) {
79+
return IRI.create(prefixIRI.substring(1, prefixIRI.length() - 1));
80+
}
81+
int sep = prefixIRI.indexOf(':');
82+
if (sep == -1) {
83+
if (getDefaultPrefix() != null) {
84+
return IRI.create(getDefaultPrefix() + prefixIRI);
85+
} else {
86+
return IRI.create(prefixIRI);
87+
}
88+
} else {
89+
String prefixName = prefixIRI.substring(0, sep + 1);
90+
if (!containsPrefixMapping(prefixName)) {
91+
throw new OWLRuntimeException(
92+
"Prefix not registered for prefix name: " + prefixName);
93+
}
94+
String prefix = getPrefix(prefixName);
95+
String localName = prefixIRI.substring(sep + 1);
96+
return IRI.create(prefix, localName);
97+
}
98+
}
99+
100+
@Nullable
101+
@Override
102+
public String getPrefixIRI(@Nonnull IRI iri) {
103+
String iriString = iri.toString();
104+
Optional<Map.Entry<String, String>> mappingOpt = nsToPrefix.entrySet().stream().filter(e -> iriString.startsWith(e.getKey())).findFirst();
105+
if (mappingOpt.isPresent()) {
106+
Map.Entry<String, String> mapping = mappingOpt.get();
107+
String localId = iriString.substring(mapping.getKey().length());
108+
return mapping.getValue() + ":" + localId;
109+
} else return null;
110+
}
111+
112+
@Nullable
113+
@Override
114+
public String getPrefixIRIIgnoreQName(@Nonnull IRI iri) {
115+
return getPrefixIRI(iri);
116+
}
117+
118+
@Nonnull
119+
@Override
120+
public Set<String> getPrefixNames() {
121+
return prefixToNS.keySet();
122+
}
123+
124+
@Override
125+
public void setDefaultPrefix(@Nullable String defaultPrefix) {
126+
}
127+
128+
@Override
129+
public void setPrefix(@Nonnull String prefixName, @Nonnull String prefix) {
130+
if (!prefixName.isEmpty() && !prefixName.equals(":") && !OBO_NS.startsWith(prefix)) {
131+
System.out.println(prefixName + " ::: " + prefix);
132+
String cleanPrefixName = prefixName;
133+
if (prefixName.endsWith(":")) {
134+
cleanPrefixName = prefixName.substring(0, prefixName.length() - 1);
135+
}
136+
prefixToNS.put(cleanPrefixName, prefix);
137+
nsToPrefix.put(prefix, cleanPrefixName);
138+
}
139+
}
140+
141+
@Override
142+
public void copyPrefixesFrom(@Nonnull PrefixManager from) {
143+
copyPrefixesFrom(from.getPrefixName2PrefixMap());
144+
}
145+
146+
@Override
147+
public void copyPrefixesFrom(@Nonnull Map<String, String> from) {
148+
for (Map.Entry<String, String> e : from.entrySet()) {
149+
String prefix = e.getKey();
150+
if (!prefix.isEmpty()) {
151+
setPrefix(e.getKey(), e.getValue());
152+
}
153+
}
154+
}
155+
156+
@Override
157+
public void unregisterNamespace(@Nonnull String namespace) {
158+
List<String> toRemove = new ArrayList<>();
159+
for (Map.Entry<String, String> e : prefixToNS.entrySet()) {
160+
if (e.getValue().equals(namespace)) {
161+
toRemove.add(e.getKey());
162+
}
163+
}
164+
for (String s : toRemove) {
165+
prefixToNS.remove(s);
166+
}
167+
nsToPrefix.remove(namespace);
168+
}
169+
170+
@Override
171+
public void clear() {
172+
prefixToNS.clear();
173+
nsToPrefix.clear();
174+
}
175+
}

oboformat/src/main/java/org/obolibrary/obo2owl/OWLAPIOwl2Obo.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ public void setObodoc(@Nonnull OBODoc obodoc) {
233233
}
234234

235235
public void setPrefixManager(@Nonnull PrefixManager manager) {
236-
this.prefixManager = manager;
236+
this.prefixManager = new OBOFormatPrefixManager(manager);
237237
}
238238

239239
/**

0 commit comments

Comments
 (0)