1 package eu.fbk.dkm.premon.premonitor;
2
3 import com.google.common.io.Files;
4 import eu.fbk.dkm.premon.util.URITreeSet;
5 import eu.fbk.dkm.premon.vocab.*;
6 import org.joox.JOOX;
7 import org.joox.Match;
8 import org.openrdf.model.URI;
9 import org.openrdf.model.vocabulary.RDF;
10 import org.openrdf.model.vocabulary.RDFS;
11 import org.openrdf.rio.RDFHandler;
12 import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory;
14 import org.w3c.dom.Document;
15 import org.w3c.dom.Element;
16 import org.w3c.dom.Node;
17 import org.w3c.dom.NodeList;
18
19 import javax.annotation.Nullable;
20 import javax.xml.parsers.DocumentBuilderFactory;
21 import java.io.File;
22 import java.io.IOException;
23 import java.util.*;
24 import java.util.regex.Matcher;
25 import java.util.regex.Pattern;
26
27
28
29
30
31
32 public class VerbnetConverter extends Converter {
33
34 private static final Logger LOGGER = LoggerFactory.getLogger(VerbnetConverter.class);
35 private static final Pattern VN_PATTERN = Pattern.compile("([^-]+)-(.*)");
36 private static final Pattern WN_PATTERN = Pattern.compile("#([^#]+)$");
37 private static final String LINK_PATTERN = "http://verbs.colorado.edu/verb-index/vn/%s.php";
38
39 private static final String DEFAULT_RESTRICTION_SUFFIX = "srs";
40 private static final String DEFAULT_FRAME_SUFFIX = "frame";
41 private static final String DEFAULT_EXAMPLE_SUFFIX = "ex";
42 private static final String DEFAULT_SYNITEM_SUFFIX = "SynItem";
43
44
45
46 ArrayList<String> pbLinks = new ArrayList<>();
47
48 public VerbnetConverter(final File path, final RDFHandler sink, final Properties properties,
49 final Map<String, URI> wnInfo) {
50 super(path, properties.getProperty("source"), sink, properties, properties
51 .getProperty("language"), wnInfo);
52
53 addLinks(this.pbLinks, properties.getProperty("linkpb"));
54 LOGGER.info("Links to: {}", this.pbLinks.toString());
55 LOGGER.info("Starting dataset: {}", this.prefix);
56 }
57
58 @Override
59 public void convert() throws IOException {
60
61 addMetaToSink();
62
63 final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
64
65 for (final File file : Files.fileTreeTraverser().preOrderTraversal(this.path)) {
66 if (!file.isDirectory() && file.getName().endsWith(".xml")) {
67 LOGGER.debug("Processing {} ...", file);
68
69 try {
70 final Document document = dbf.newDocumentBuilder().parse(file);
71 final Match vnClass = JOOX.$(document.getElementsByTagName("VNCLASS"));
72
73 for (final Element thisClass : vnClass) {
74
75
76
77
78
79
80
81 addClassToSink(thisClass, null, null, null);
82
83 }
84
85 } catch (final Exception ex) {
86 throw new IOException(ex);
87 }
88 }
89 }
90
91 }
92
93 private void addClassToSink(final Element thisClass, @Nullable final URI superClass,
94 @Nullable final HashMap<String, Element> themRolesElements,
95 @Nullable final HashSet<URI> framesElements) {
96 final String id = thisClass.getAttribute("ID");
97
98 final Matcher matcher = VN_PATTERN.matcher(id);
99 if (!matcher.find()) {
100 LOGGER.error("Class ID {} does not match", id);
101 return;
102 }
103
104
105 final String type = "v";
106
107 final URI rolesetURI = uriForRoleset(id);
108 if (superClass == null) {
109 addStatementToSink(rolesetURI, RDFS.SEEALSO, getExternalLink(id));
110 } else {
111 addStatementToSink(rolesetURI, PMOVN.SUBCLASS_OF, superClass);
112 }
113
114 addStatementToSink(rolesetURI, RDF.TYPE, PMOVN.VERB_CLASS);
115 addStatementToSink(rolesetURI, RDFS.LABEL, id, false);
116
117 Match elements;
118 final HashMap<String, URI> lemmas = new HashMap<>();
119
120 elements = JOOX.$(thisClass).xpath("MEMBERS/MEMBER");
121 for (final Element member : elements) {
122 String uriLemma = member.getAttribute("name");
123 uriLemma = uriLemma.replaceAll("_", "+");
124 final String goodLemma = uriLemma.replaceAll("\\+", " ");
125
126 final String groupingString = member.getAttribute("grouping");
127 final String wnString = member.getAttribute("wn");
128
129 final URI lexicalEntryURI = addLexicalEntry(goodLemma, uriLemma, null, null, "v",
130 getLexicon());
131 lemmas.put(uriLemma, lexicalEntryURI);
132 addStatementToSink(lexicalEntryURI, ONTOLEX.EVOKES, rolesetURI);
133
134 final URI conceptualizationURI = uriForConceptualization(uriLemma, type, id);
135 addStatementToSink(conceptualizationURI, RDF.TYPE, PMO.CONCEPTUALIZATION);
136 addStatementToSink(conceptualizationURI, PMO.EVOKING_ENTRY, lexicalEntryURI);
137 addStatementToSink(conceptualizationURI, PMO.EVOKED_CONCEPT, rolesetURI);
138
139 final TreeSet<URI> mapping = new URITreeSet();
140 mapping.add(conceptualizationURI);
141
142 if (groupingString != null && groupingString.trim().length() > 0) {
143 final String[] groupings = groupingString.trim().split("\\s+");
144 for (final String grouping : groupings) {
145 for (final String pbLink : this.pbLinks) {
146 if (pbLink.length() == 0) {
147 continue;
148 }
149
150 final URI pbRolesetURI = uriForRoleset(grouping, pbLink);
151 final URI pbConceptualizationURI = uriForConceptualizationWithPrefix(
152 uriLemma, "v", grouping, pbLink);
153
154 addStatementToSink(pbConceptualizationURI, RDF.TYPE, PMO.CONCEPTUALIZATION);
155
156
157
158
159
160 mapping.add(pbConceptualizationURI);
161 }
162 }
163 }
164
165 if (wnString != null && this.wnInfo.size() > 0) {
166 final String[] wns = wnString.split("\\s+");
167
168 for (String wn : wns) {
169
170 wn = wn.trim();
171
172 if (wn.length() == 0) {
173 continue;
174 }
175
176 boolean questionMark = false;
177 if (wn.startsWith("?")) {
178
179 questionMark = true;
180 wn = wn.substring(1);
181 }
182
183 final URI wnURI = this.wnInfo.get(wn);
184
185 if (wnURI == null) {
186 LOGGER.warn("No wnURI found for {}", wn);
187 continue;
188 }
189
190 String lemma = wn.substring(0, wn.indexOf('%'));
191 final URI reference = this.wnInfo.get(wnURI.toString() + "|" + lemma);
192
193 if (reference == null) {
194 LOGGER.warn("No reference found for {} / {}", wnURI.toString(), lemma);
195 continue;
196 }
197
198 final Matcher m = WN_PATTERN.matcher(reference.toString());
199 if (!m.find()) {
200 continue;
201 }
202
203 final URI wnConceptualizationURI = uriForConceptualizationWithPrefix(uriLemma,
204 "v", wnURI.toString().replace(WN_NAMESPACE,""), "wn31");
205
206 addStatementToSink(wnConceptualizationURI, RDF.TYPE, PMO.CONCEPTUALIZATION);
207 addStatementToSink(wnConceptualizationURI, PMO.EVOKING_ENTRY, lexicalEntryURI);
208 addStatementToSink(wnConceptualizationURI, RDFS.SEEALSO, reference);
209 addStatementToSink(wnConceptualizationURI, PMO.EVOKED_CONCEPT, wnURI);
210
211
212 mapping.add(wnConceptualizationURI);
213
214
215
216
217
218
219 }
220
221 }
222
223
224 if (mapping.size() >= 2) {
225 addMappingToSink(null, mapping, DEFAULT_SENSE_SUFFIX, prefix);
226 }
227 }
228
229
230 HashMap<String, Element> thisThemRolesElements = new HashMap<>();
231 if (themRolesElements != null) {
232 thisThemRolesElements = new HashMap<>(themRolesElements);
233 }
234 elements = JOOX.$(thisClass).xpath("THEMROLES/THEMROLE");
235 for (final Element element : elements) {
236 final String argName = element.getAttribute("type");
237 thisThemRolesElements.put(argName, element);
238 final URI argumentURI = uriForArgument(id, argName);
239 addStatementToSink(rolesetURI, PMOVN.DEFINES_SEM_ROLE, argumentURI);
240 }
241
242 for (final String argName : thisThemRolesElements.keySet()) {
243 final Element element = thisThemRolesElements.get(argName);
244
245 final URI argumentURI = uriForArgument(id, argName);
246
247 addStatementToSink(rolesetURI, PMO.SEM_ROLE, argumentURI);
248 addStatementToSink(argumentURI, RDF.TYPE, PMOVN.SEMANTIC_ROLE);
249 addStatementToSink(argumentURI, PMOVN.THEMATIC_ROLE_P, PMOVN.lookup(PMOVN.THEMATIC_ROLE_C, argName));
250
251
252
253
254
255
256
257
258
259
260
261 addRestrictions("SELRESTRS", "SELRESTR", argumentURI, element, "srs",
262 PMOVN.ROLE_SELECTIONAL_RESTRICTION, PMOVN.ROLE_RESTRICTION_PROPERTY);
263 }
264
265 elements = JOOX.$(thisClass).xpath("FRAMES/FRAME");
266
267 final HashSet<URI> framesToPass = new HashSet<>();
268
269 if (framesElements != null) {
270 for (final URI framesElement : framesElements) {
271 addStatementToSink(rolesetURI, PMOVN.FRAME, framesElement);
272 }
273 framesToPass.addAll(framesElements);
274 }
275 final Set<URI> thisClassFrames = addFrames(elements, id);
276 framesToPass.addAll(thisClassFrames);
277
278 elements = JOOX.$(thisClass).xpath("SUBCLASSES/VNSUBCLASS");
279 for (final Element element : elements) {
280 addClassToSink(element, rolesetURI, thisThemRolesElements, framesToPass);
281 }
282
283 }
284
285 private Set<URI> addFrames(final Match frames, final String id) {
286
287 final Set<URI> frameURIs = new HashSet<>();
288
289 final int totalSize = frames.size();
290 if (totalSize == 1) {
291 final URI frameURI = getFrameURI(id);
292 frameURIs.add(frameURI);
293 for (final Element element : frames) {
294 addFrameToSink(id, frameURI, element);
295 }
296 }
297 if (totalSize > 1) {
298 int thisSize = 0;
299 for (final Element element : frames) {
300 thisSize++;
301
302 final URI frameURI = getFrameURI(id, thisSize);
303 frameURIs.add(frameURI);
304 addFrameToSink(id, frameURI, element);
305 }
306 }
307
308 return frameURIs;
309 }
310
311 private void addRestrictions(final String label1, final String label2, final URI startingURI,
312 final Element element, final String suffix, final URI typeURI, final URI lookup) {
313 addRestrictions(label1, label2, startingURI, element, suffix, typeURI, lookup, null, null,
314 null);
315 }
316
317 private void addRestrictions(final String label1, final String label2, final URI startingURI,
318 final Element element, final String suffix, final URI typeURI, final URI lookup,
319 @Nullable final List<String> pieces, @Nullable final String sep1,
320 @Nullable final String sep2) {
321 final Match selrestrses = JOOX.$(element.getElementsByTagName(label1));
322 for (final Element selrestrse : selrestrses) {
323
324 final Match selrestrs = JOOX.$(selrestrse.getElementsByTagName(label2));
325 final URI restrictionURI = uriForRestriction(startingURI, suffix);
326 if (selrestrs.size() == 1) {
327 final URI voURI = PMOVN.lookup(lookup, selrestrs.get(0).getAttribute("type"));
328 if (voURI == null) {
329 LOGGER.error("Value not found: {}:{}", lookup,
330 selrestrs.get(0).getAttribute("type"));
331 }
332 addStatementToSink(startingURI, PMOVN.RESTRICTION_P, restrictionURI);
333 addStatementToSink(restrictionURI, RDF.TYPE, typeURI);
334 addStatementToSink(restrictionURI, RDF.TYPE, getAtomicURI(selrestrs.get(0)));
335 addStatementToSink(restrictionURI, PMO.VALUE_OBJ, voURI);
336 if (pieces != null) {
337 pieces.add(String.format("%s%s%s%s", sep1,
338 selrestrs.get(0).getAttribute("Value"),
339 selrestrs.get(0).getAttribute("type"), sep2));
340 }
341 }
342 if (selrestrs.size() > 1) {
343
344 final URI logicURI = getLogicURI(selrestrse);
345
346 addStatementToSink(startingURI, PMOVN.RESTRICTION_P, restrictionURI);
347 addStatementToSink(restrictionURI, RDF.TYPE, logicURI);
348 addStatementToSink(restrictionURI, RDF.TYPE, typeURI);
349
350 int i = 0;
351 for (final Element selrestr : selrestrs) {
352 i++;
353 final URI thisRestrictionURI = uriForRestriction(startingURI, suffix, i);
354
355 final URI voURI = PMOVN.lookup(lookup, selrestr.getAttribute("type"));
356 if (voURI == null) {
357 LOGGER.error("Value not found: {}:{}", lookup,
358 selrestr.getAttribute("type"));
359 }
360 addStatementToSink(restrictionURI, PMO.ITEM, thisRestrictionURI);
361 addStatementToSink(thisRestrictionURI, RDF.TYPE, typeURI);
362 addStatementToSink(thisRestrictionURI, RDF.TYPE, getAtomicURI(selrestr));
363 addStatementToSink(thisRestrictionURI, PMO.VALUE_OBJ, voURI);
364 if (pieces != null) {
365 pieces.add(String.format("%s%s%s%s", sep1, selrestr.getAttribute("Value"),
366 selrestr.getAttribute("type"), sep2));
367 }
368 }
369 }
370
371 }
372 }
373
374 private void addFrameToSink(final String classID, final URI frameURI,
375 final Element frameElement) {
376
377 final URI classURI = uriForRoleset(classID);
378 addStatementToSink(classURI, PMOVN.FRAME, frameURI);
379 addStatementToSink(classURI, PMOVN.DEFINES_FRAME, frameURI);
380
381 addStatementToSink(frameURI, RDF.TYPE, PMOVN.VERBNET_FRAME);
382
383 final Match description = JOOX.$(frameElement.getElementsByTagName("DESCRIPTION"));
384 addStatementToSink(frameURI, PMOVN.FRAME_DESC_NUMBER,
385 description.attr("descriptionNumber"));
386 addStatementToSink(frameURI, PMOVN.FRAME_PRIMARY, description.attr("primary"));
387 addStatementToSink(frameURI, PMOVN.FRAME_SECONDARY, description.attr("secondary"));
388 addStatementToSink(frameURI, PMOVN.FRAME_XTAG, description.attr("xtag"));
389
390 final Map<URI, URI> exampleURIs = new HashMap<>();
391
392 final Match examples = JOOX.$(frameElement.getElementsByTagName("EXAMPLE"));
393 if (examples.size() == 1) {
394 final URI exampleURI = getExampleURI(frameURI);
395 final URI uri = addExampleToSink(frameURI, exampleURI, examples.get(0));
396 exampleURIs.put(exampleURI, uri);
397 }
398 if (examples.size() > 1) {
399 int i = 0;
400 for (final Element example : examples) {
401 i++;
402
403 final URI exampleURI = getExampleURI(frameURI, i);
404 final URI uri = addExampleToSink(frameURI, exampleURI, example);
405 exampleURIs.put(exampleURI, uri);
406 }
407 }
408
409 final Match syntax = JOOX.$(frameElement.getElementsByTagName("SYNTAX"));
410 if (syntax.size() == 1) {
411 final Element syntaxElement = syntax.get(0);
412 final SyntaxArrayLogic syntaxArrayLogic = new SyntaxArrayLogic(syntaxElement,
413 frameURI, classID);
414 syntaxArrayLogic.add();
415
416 for (final URI exampleURI : exampleURIs.keySet()) {
417 final URI annotationSetURI = exampleURIs.get(exampleURI);
418
419 addStatementToSink(frameURI, PMOVN.FRAME_EXAMPLE, exampleURI, this.EXAMPLE_GRAPH);
420
421 final URI predURI = createURI(annotationSetURI.toString() + "-pred");
422 addStatementToSink(predURI, RDF.TYPE, NIF.ANNOTATION_C, this.EXAMPLE_GRAPH);
423 addStatementToSink(annotationSetURI, PMO.ITEM, predURI, this.EXAMPLE_GRAPH);
424 addStatementToSink(exampleURI, NIF.ANNOTATION_P, predURI, this.EXAMPLE_GRAPH);
425 addStatementToSink(predURI, PMO.VALUE_OBJ, classURI, this.EXAMPLE_GRAPH);
426
427 for (final String role : syntaxArrayLogic.getRoles()) {
428 final String rolePart = formatArg(role);
429 final URI roleURI = createURI(annotationSetURI.toString() + "-" + rolePart);
430 final URI argumentURI = uriForArgument(classID, role);
431
432 addStatementToSink(roleURI, RDF.TYPE, NIF.ANNOTATION_C, this.EXAMPLE_GRAPH);
433 addStatementToSink(annotationSetURI, PMO.ITEM, roleURI, this.EXAMPLE_GRAPH);
434 addStatementToSink(exampleURI, NIF.ANNOTATION_P, roleURI, this.EXAMPLE_GRAPH);
435 addStatementToSink(roleURI, PMO.VALUE_OBJ, argumentURI, this.EXAMPLE_GRAPH);
436 }
437
438 }
439
440 String pieces = String.join(" ", syntaxArrayLogic.getPieces());
441 pieces = pieces.trim();
442 if (pieces.length() > 0) {
443 addStatementToSink(frameURI, PMOVN.FRAME_SYNTAX_DESCRIPTION, pieces, false);
444 }
445 } else {
446 LOGGER.warn("Syntax size is not 1");
447 }
448
449 final Match semantics = JOOX.$(frameElement.getElementsByTagName("SEMANTICS"));
450 if (semantics.size() == 1) {
451 final Element semanticsElement = semantics.get(0);
452 final SemanticsArrayLogic semanticsArrayLogic = new SemanticsArrayLogic(
453 semanticsElement, frameURI, classID);
454 semanticsArrayLogic.add();
455
456 String pieces = String.join(" ", semanticsArrayLogic.getPieces());
457 pieces = pieces.trim();
458 if (pieces.length() > 0) {
459 addStatementToSink(frameURI, PMOVN.FRAME_SEMANTICS_DESCRIPTION, pieces, false);
460 }
461 }
462 }
463
464 class ArgumentArrayLogic extends ArrayLogicClass {
465
466 protected String rolesetID;
467
468 List<String> pieces = new ArrayList<>();
469
470 public List<String> getPieces() {
471 return this.pieces;
472 }
473
474 public void resetPieces() {
475 this.pieces = new ArrayList<>();
476 }
477
478 public ArgumentArrayLogic(final Element startElement, final URI parentURI,
479 final String rolesetID) {
480 super(startElement, parentURI);
481 this.rolesetID = rolesetID;
482 }
483
484 @Override void addToSink(final Element element, final URI thisURI) {
485 addStatementToSink(thisURI, RDF.TYPE, PMOVN.PRED_ARG);
486 final String type = element.getAttribute("type");
487 String value = element.getAttribute("value");
488 this.pieces.add(value);
489
490 boolean questionMark = false;
491
492 if (value.startsWith("?")) {
493 addStatementToSink(thisURI, PMOVN.IMPL_PRED_ARG,true);
494 value = value.substring(1);
495 questionMark = true;
496 } else addStatementToSink(thisURI, PMOVN.IMPL_PRED_ARG,false);
497
498 addStatementToSink(thisURI, PMO.VALUE_DT, value);
499
500 switch (type) {
501 case "Event":
502 addStatementToSink(thisURI, RDF.TYPE, PMOVN.EVENT_PRED_ARG);
503 final String okValue = value.replaceAll("\\(.*\\)", "");
504 final URI argType = PMOVN.lookup(PMOVN.EVENT_PRED_ARG_TYPE, okValue);
505 if (argType != null) {
506 addStatementToSink(thisURI, PMO.VALUE_OBJ, argType);
507 }
508 break;
509 case "Constant":
510 addStatementToSink(thisURI, RDF.TYPE, PMOVN.CONSTANT_PRED_ARG);
511 break;
512 case "ThemRole":
513 addStatementToSink(thisURI, RDF.TYPE, PMOVN.THEM_ROLE_PRED_ARG);
514
515
516 final String[] parts = value.split("\\+|,");
517 for (String part : parts) {
518 part = part.replaceAll("_[ij]$", "");
519 part = part.trim();
520
521
522 final URI thematicRoleURI = PMOVN.lookup(PMOVN.THEMATIC_ROLE_C, part);
523
524 addStatementToSink(thisURI, PMO.VALUE_OBJ, thematicRoleURI);
525 }
526 break;
527 case "VerbSpecific":
528 addStatementToSink(thisURI, RDF.TYPE, PMOVN.VERB_SPECIFIC_PRED_ARG);
529 break;
530 }
531 }
532
533 @Override String getSuffix() {
534 return DEFAULT_ARG_SUFFIX;
535 }
536 }
537
538 class SemanticsArrayLogic extends ArrayLogicClass {
539
540 protected String rolesetID;
541 List<String> pieces = new ArrayList<>();
542
543 public List<String> getPieces() {
544 return this.pieces;
545 }
546
547 public void resetPieces() {
548 this.pieces = new ArrayList<>();
549 }
550
551 public SemanticsArrayLogic(final Element startElement, final URI parentURI,
552 final String rolesetID) {
553 super(startElement, parentURI);
554 this.rolesetID = rolesetID;
555 }
556
557 @Override String getSuffix() {
558 return DEFAULT_PRED_SUFFIX;
559 }
560
561 @Override void addToSink(final Element element, final URI thisURI) {
562 final String value = element.getAttribute("value");
563 final URI obj = PMOVN.createURI(value + "_pred");
564
565 addStatementToSink(obj, RDF.TYPE, PMOVN.PRED_TYPE);
566 addStatementToSink(obj, RDFS.LABEL, value);
567
568
569
570 URI thisA = PMOVN.PRED;
571 final String bool = element.getAttribute("bool");
572 if (bool != null && bool.equals("!")) {
573 addStatementToSink(thisURI, PMOVN.NEG_PRE, true);
574 } else {
575 addStatementToSink(thisURI, PMOVN.NEG_PRE, false);
576 }
577 addStatementToSink(thisURI, RDF.TYPE, thisA);
578 addStatementToSink(thisURI, PMO.VALUE_OBJ, obj);
579
580 final Match args = JOOX.$(element.getElementsByTagName("ARGS"));
581 String argString = "";
582 if (args.size() == 1) {
583 final Element argElement = args.get(0);
584 final ArgumentArrayLogic argumentArrayLogic = new ArgumentArrayLogic(argElement,
585 thisURI, this.rolesetID);
586 argumentArrayLogic.add();
587
588 argString = String.join(", ", argumentArrayLogic.getPieces());
589 } else {
590 LOGGER.warn("Args size is not 1");
591 }
592
593 String semString = String.format("%s(%s)", value, argString.trim());
594 if (bool != null && bool.equals("!")) {
595 semString = String.format("not(%s)", semString);
596 }
597 this.pieces.add(semString);
598 }
599 }
600
601 class SyntaxArrayLogic extends ArrayLogicClass {
602
603 protected String rolesetID;
604 List<String> pieces = new ArrayList<>();
605 List<String> roles = new ArrayList<>();
606
607 public List<String> getPieces() {
608 return this.pieces;
609 }
610
611 public void resetPieces() {
612 this.pieces = new ArrayList<>();
613 }
614
615 public SyntaxArrayLogic(final Element startElement, final URI parentURI,
616 final String rolesetID) {
617 super(startElement, parentURI);
618 this.rolesetID = rolesetID;
619 }
620
621 public List<String> getRoles() {
622 return this.roles;
623 }
624
625 @Override String getSuffix() {
626 return DEFAULT_SYNITEM_SUFFIX;
627 }
628
629 @Override void addToSink(final Element element, final URI thisURI) {
630 final String tagName = element.getTagName();
631
632 final String value = element.getAttribute("value");
633
634
635
636
637
638
639
640
641
642 switch (tagName) {
643 case "NP":
644 this.pieces.add(value);
645 this.roles.add(value);
646 addStatementToSink(thisURI, RDF.TYPE, PMOVN.NP_SYN_ITEM);
647 final URI argumentURI = uriForArgument(this.rolesetID, value);
648 addStatementToSink(thisURI, PMO.VALUE_OBJ, argumentURI);
649 addRestrictions("SYNRESTRS", "SYNRESTR", thisURI, element, "synRes",
650 PMOVN.SYNTACTIC_RESTRICTION, PMOVN.SYNTACTIC_RESTRICTION_PROPERTY,
651 this.pieces, "[", "]");
652 addRestrictions("SELRESTRS", "SELRESTR", thisURI, element, "selRes",
653 PMOVN.ROLE_SELECTIONAL_RESTRICTION, PMOVN.ROLE_RESTRICTION_PROPERTY,
654 this.pieces, "{{", "}}");
655 break;
656 case "VERB":
657 this.pieces.add("V");
658 addStatementToSink(thisURI, RDF.TYPE, PMOVN.VERB_SYN_ITEM);
659 break;
660 case "PREP":
661 if (value != null && value.length() > 0) {
662 this.pieces.add(String.format("{%s}", value));
663 final String[] values = value.split("\\s+");
664 for (final String thisValue : values) {
665 final URI lexicalEntryURI = addLexicalEntry(thisValue, thisValue, null,
666 null, "prep", getLexicon());
667 addStatementToSink(thisURI, PMO.VALUE_OBJ, lexicalEntryURI);
668 }
669 }
670 addStatementToSink(thisURI, RDF.TYPE, PMOVN.PREP_SYN_ITEM);
671 addRestrictions("SELRESTRS", "SELRESTR", thisURI, element, "selRes",
672 PMOVN.PREPOSITION_SELECTIONAL_RESTRICTION,
673 PMOVN.PREPOSITION_RESTRICTION_PROPERTY, this.pieces, "{{", "}}");
674 break;
675 case "LEX":
676 this.pieces.add(String.format("(%s)", value));
677 addStatementToSink(thisURI, RDF.TYPE, PMOVN.LEX_SYN_ITEM);
678 addStatementToSink(thisURI, PMO.VALUE_DT, value);
679 break;
680 case "ADV":
681 this.pieces.add("ADV");
682 addStatementToSink(thisURI, RDF.TYPE, PMOVN.ADV_SYN_ITEM);
683 break;
684 case "ADJ":
685 this.pieces.add("ADJ");
686 addStatementToSink(thisURI, RDF.TYPE, PMOVN.ADJ_SYN_ITEM);
687 break;
688 }
689 }
690 }
691
692 abstract class ArrayLogicClass {
693
694 protected Element startElement;
695 protected URI parentURI;
696
697 public ArrayLogicClass(final Element startElement, final URI parentURI) {
698 this.startElement = startElement;
699 this.parentURI = parentURI;
700 }
701
702 public void add() {
703 final NodeList childNodes = this.startElement.getChildNodes();
704 int count = 0;
705 final List<URI> list = new ArrayList<>();
706
707 for (int i = 0; i < childNodes.getLength(); i++) {
708 final Node node = childNodes.item(i);
709 if (node.getNodeType() == Node.ELEMENT_NODE) {
710 final Element element = (Element) node;
711 count++;
712
713 final URI thisSysURI = getThisURI(count);
714 list.add(thisSysURI);
715 addToSink(element, thisSysURI);
716 }
717 }
718
719 boolean isFirst = true;
720 URI prev = null;
721 for (final URI uri : list) {
722 if (isFirst) {
723 addStatementToSink(this.parentURI, PMO.FIRST, uri);
724 isFirst = false;
725 }
726
727 if (prev != null) {
728 addStatementToSink(prev, PMO.NEXT, uri);
729 }
730
731 prev = uri;
732 }
733 }
734
735 URI getThisURI(final Integer index) {
736 final StringBuilder builder = new StringBuilder();
737 builder.append(this.parentURI.toString());
738 builder.append("_");
739 builder.append(getSuffix());
740 if (index != null) {
741 builder.append("_").append(index);
742 }
743 return createURI(builder.toString());
744 }
745
746 abstract void addToSink(Element element, URI thisURI);
747
748 abstract String getSuffix();
749 }
750
751 private URI addExampleToSink(final URI frameURI, final URI exampleURI, final Element example) {
752
753 final URI annotationSetURI = uriForAnnotationSet(exampleURI, null);
754
755 addStatementToSink(annotationSetURI, RDF.TYPE, PMO.ANNOTATION_SET, this.EXAMPLE_GRAPH);
756
757
758 addStatementToSink(exampleURI, RDF.TYPE, PMO.EXAMPLE, this.EXAMPLE_GRAPH);
759 addStatementToSink(exampleURI, NIF.IS_STRING, example.getTextContent(), this.EXAMPLE_GRAPH);
760
761 return annotationSetURI;
762 }
763
764 private URI getExampleURI(final URI frameURI) {
765 return getExampleURI(frameURI, null);
766 }
767
768 private URI getExampleURI(final URI frameURI, @Nullable final Integer index) {
769 final StringBuilder builder = new StringBuilder();
770 builder.append(frameURI.toString());
771 builder.append("_");
772 builder.append(DEFAULT_EXAMPLE_SUFFIX);
773 if (index != null) {
774 builder.append("_").append(index);
775 }
776 return createURI(builder.toString());
777 }
778
779 private URI getFrameURI(final String rolesetID) {
780 return getFrameURI(rolesetID, null);
781 }
782
783 private URI getFrameURI(final String rolesetID, @Nullable final Integer index) {
784 final StringBuilder builder = new StringBuilder();
785 builder.append(NAMESPACE);
786 builder.append(rolesetPart(rolesetID));
787 builder.append("_");
788 builder.append(DEFAULT_FRAME_SUFFIX);
789 if (index != null) {
790 builder.append("_").append(index);
791 }
792 return createURI(builder.toString());
793 }
794
795 private URI getLogicURI(final Element selrestrse) {
796 final String logic = selrestrse.getAttribute("logic");
797 if (logic != null && logic.equals("or")) {
798 return PMOVN.OR_COMPOUND_RESTRICTION;
799 }
800
801 return PMOVN.AND_COMPOUND_RESTRICTION;
802 }
803
804 private URI getAtomicURI(final Element element) {
805 final String value = element.getAttribute("Value");
806 if (value.equals("+")) {
807 return PMOVN.EXIST_ATOMIC_RESTRICTION;
808 }
809 if (value.equals("-")) {
810 return PMOVN.ABSENT_ATOMIC_RESTRICTION;
811 }
812
813 return null;
814 }
815
816 @Override
817 public String getArgLabel() {
818 return "";
819 }
820
821 protected URI getExternalLink(final String id) {
822 return createURI(String.format(LINK_PATTERN, id));
823 }
824
825 protected URI uriForRestriction(final URI start, @Nullable final String suffix) {
826 return uriForRestriction(start, suffix, null);
827 }
828
829 protected URI uriForRestriction(final URI start, @Nullable final String suffix,
830 @Nullable final Integer index) {
831 final StringBuilder builder = new StringBuilder();
832 builder.append(start.toString());
833 builder.append("_");
834 builder.append(suffix != null ? suffix : DEFAULT_RESTRICTION_SUFFIX);
835 if (index != null) {
836 builder.append("_").append(index);
837 }
838 return createURI(builder.toString());
839 }
840
841 @Override
842 protected String formatArg(final String arg) {
843 return super.formatArg(arg).toLowerCase();
844 }
845
846 @Override
847 protected URI getPosURI(final String textualPOS) {
848 switch (textualPOS) {
849 case "prep":
850 return LEXINFO.PREPOSITION;
851 }
852
853 return LEXINFO.VERB;
854 }
855 }