001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.marshall.jena; 018 019import static org.apache.juneau.commons.utils.CollectionUtils.*; 020import static org.apache.juneau.commons.utils.Shorts.*; 021import static org.apache.juneau.commons.utils.SystemUtils.*; 022 023import java.util.*; 024import java.util.concurrent.*; 025 026import org.apache.juneau.commons.bean.*; 027import org.apache.juneau.commons.collections.*; 028import org.apache.juneau.marshall.*; 029import org.apache.juneau.marshall.serializer.*; 030import org.apache.juneau.marshall.xml.*; 031 032/** 033 * Serializes POJOs to RDF. 034 * 035 * <h5 class='topic'>Behavior-specific subclasses</h5> 036 * <p> 037 * The following direct subclasses are provided for language-specific serializers: 038 * <ul> 039 * <li>{@link RdfXmlSerializer} - RDF/XML. 040 * <li>{@link RdfXmlAbbrevSerializer} - RDF/XML-ABBREV. 041 * <li>{@link NTripleSerializer} - N-TRIPLE. 042 * <li>{@link TurtleSerializer} - TURTLE. 043 * <li>{@link N3Serializer} - N3. 044 * </ul> 045 * 046 * <h5 class='section'>Notes:</h5><ul> 047 * <li class='note'>This class is thread safe and reusable. 048 * </ul> 049 * 050 * <h5 class='section'>See Also:</h5><ul> 051 * <li class='link'>{doc jmr.RdfDetails} 052 053 * </ul> 054 */ 055@SuppressWarnings({ 056 "java:S100", // Builder methods use underscore-separated namespacing convention (e.g. n3_disableAbbrevBaseUri, rdfxml_xmlbase) to group related settings by Jena component 057 "java:S110", // Inheritance depth exceeds 5; necessary to participate in the serializer hierarchy 058 "java:S1192" // Duplicated literals (argument/property names) read more clearly inline than as constants 059}) 060public class RdfSerializer extends WriterSerializer implements RdfMetaProvider { 061 062 // Media type and language constants 063 private static final String LANG_RDF_XML_ABBREV = "RDF/XML-ABBREV"; 064 private static final String MT_TEXT_XML_RDF = "text/xml+rdf"; 065 066 /** 067 * Builder class. 068 */ 069 @SuppressWarnings({ 070 "java:S119" // 'SELF' (CRTP self-type) is intentional and clearer than a single-letter name. 071 }) 072 public abstract static class Builder<SELF extends Builder<SELF>> extends WriterSerializer.Builder<SELF> { 073 074 private static final Cache<HashKey,RdfSerializer> CACHE = Cache.of(HashKey.class, RdfSerializer.class).build(); 075 076 private static final Namespace DEFAULT_JUNEAU_NS = Namespace.of("j", "http://www.apache.org/juneau/"); 077 private static final Namespace DEFAULT_JUNEAUBP_NS = Namespace.of("jp", "http://www.apache.org/juneaubp/"); 078 079 boolean addBeanTypesRdf; 080 boolean addLiteralTypes; 081 boolean addRootProperty; 082 boolean disableAutoDetectNamespaces; 083 boolean disableUseXmlNamespaces; 084 boolean looseCollections; 085 String language; 086 Namespace juneauNs; 087 Namespace juneauBpNs; 088 RdfCollectionFormat collectionFormat; 089 List<Namespace> namespaces; 090 Map<String,Object> jenaSettings; 091 092 /** 093 * Constructor, default settings. 094 */ 095 protected Builder() { 096 super(); 097 addBeanTypesRdf = env("Rdf.addBeanTypesRdf", false); 098 addLiteralTypes = env("Rdf.addLiteralTypes", false); 099 addRootProperty = env("Rdf.addRootProperty", false); 100 disableAutoDetectNamespaces = env("Rdf.disableAutoDetectNamespaces", false); 101 disableUseXmlNamespaces = env("Rdf.disableUseXmlNamespaces", false); 102 looseCollections = env("Rdf.looseCollections", false); 103 language = env("Rdf.language", LANG_RDF_XML_ABBREV); 104 collectionFormat = env("Rdf.collectionFormat", RdfCollectionFormat.DEFAULT); 105 juneauNs = DEFAULT_JUNEAU_NS; 106 juneauBpNs = DEFAULT_JUNEAUBP_NS; 107 namespaces = null; 108 jenaSettings = new TreeMap<>(); 109 } 110 111 /** 112 * Copy constructor. 113 * 114 * @param copyFrom The builder to copy from. 115 * <br>Cannot be <jk>null</jk>. 116 */ 117 protected Builder(Builder<?> copyFrom) { 118 super(reqnn("copyFrom", copyFrom)); 119 addBeanTypesRdf = copyFrom.addBeanTypesRdf; 120 addLiteralTypes = copyFrom.addLiteralTypes; 121 addRootProperty = copyFrom.addRootProperty; 122 collectionFormat = copyFrom.collectionFormat; 123 disableAutoDetectNamespaces = copyFrom.disableAutoDetectNamespaces; 124 disableUseXmlNamespaces = copyFrom.disableUseXmlNamespaces; 125 juneauBpNs = copyFrom.juneauBpNs; 126 juneauNs = copyFrom.juneauNs; 127 language = copyFrom.language; 128 looseCollections = copyFrom.looseCollections; 129 namespaces = copyFrom.namespaces; 130 jenaSettings = new TreeMap<>(copyFrom.jenaSettings); 131 } 132 133 /** 134 * Copy constructor. 135 * 136 * @param copyFrom The bean to copy from. 137 * <br>Cannot be <jk>null</jk>. 138 */ 139 protected Builder(RdfSerializer copyFrom) { 140 super(reqnn("copyFrom", copyFrom)); 141 addBeanTypesRdf = copyFrom.addBeanTypesRdf; 142 addLiteralTypes = copyFrom.addLiteralTypes; 143 addRootProperty = copyFrom.addRootProperty; 144 collectionFormat = copyFrom.collectionFormat; 145 disableAutoDetectNamespaces = ! copyFrom.autoDetectNamespaces; 146 disableUseXmlNamespaces = ! copyFrom.useXmlNamespaces; 147 juneauBpNs = copyFrom.juneauBpNs; 148 juneauNs = copyFrom.juneauNs; 149 language = copyFrom.language; 150 looseCollections = copyFrom.looseCollections; 151 namespaces = copyFrom.namespaces.length == 0 ? null : list(copyFrom.namespaces); 152 jenaSettings = new TreeMap<>(copyFrom.jenaSettings); 153 } 154 155 /** 156 * Add <js>"_type"</js> properties when needed. 157 * 158 * <p> 159 * If <jk>true</jk>, then <js>"_type"</js> properties will be added to beans if their type cannot be inferred 160 * through reflection. 161 * 162 * <p> 163 * When present, this value overrides the {@link org.apache.juneau.marshall.serializer.Serializer.Builder#addBeanTypes() Serializer.Builder#addBeanTypes()} setting and is 164 * provided to customize the behavior of specific serializers in a {@link SerializerSet}. 165 * 166 * @return This object. 167 */ 168 public SELF addBeanTypesRdf() { 169 return addBeanTypesRdf(true); 170 } 171 172 /** 173 * Same as {@link #addBeanTypesRdf()} but allows you to explicitly specify the value. 174 * 175 * @param value The value for this setting. 176 * @return This object. 177 */ 178 public SELF addBeanTypesRdf(boolean value) { 179 addBeanTypesRdf = value; 180 return self(); 181 } 182 183 /** 184 * Add XSI data types to non-<c>String</c> literals. 185 * 186 * <p> 187 * Shortcut for calling <code>addLiteralTypes(<jk>true</jk>)</code>. 188 * 189 * @return This object. 190 */ 191 public SELF addLiteralTypes() { 192 return addLiteralTypes(true); 193 } 194 195 /** 196 * Add XSI data types to non-<c>String</c> literals. 197 * 198 * <p> 199 * Shortcut for calling <code>addLiteralTypes(<jk>true</jk>)</code>. 200 * 201 * @param value 202 * The new value for this setting. 203 * @return This object. 204 */ 205 public SELF addLiteralTypes(boolean value) { 206 addLiteralTypes = value; 207 return self(); 208 } 209 210 /** 211 * Add RDF root identifier property to root node. 212 * 213 * <p> 214 * When enabled an RDF property <c>http://www.apache.org/juneau/root</c> is added with a value of <js>"true"</js> 215 * to identify the root node in the graph. 216 * <br>This helps locate the root node during parsing. 217 * 218 * <p> 219 * If disabled, the parser has to search through the model to find any resources without incoming predicates to 220 * identify root notes, which can introduce a considerable performance degradation. 221 * 222 * @return This object. 223 */ 224 public SELF addRootProperty() { 225 return addRootProperty(true); 226 } 227 228 /** 229 * Add RDF root identifier property to root node. 230 * 231 * <p> 232 * When enabled an RDF property <c>http://www.apache.org/juneau/root</c> is added with a value of <js>"true"</js> 233 * to identify the root node in the graph. 234 * <br>This helps locate the root node during parsing. 235 * 236 * <p> 237 * If disabled, the parser has to search through the model to find any resources without incoming predicates to 238 * identify root notes, which can introduce a considerable performance degradation. 239 * 240 * @param value 241 * The new value for this setting. 242 * @return This object. 243 */ 244 public SELF addRootProperty(boolean value) { 245 addRootProperty = value; 246 return self(); 247 } 248 249 @Override /* Overridden from Context.Builder<?> */ 250 public RdfSerializer build() { 251 return cache(CACHE).build(RdfSerializer.class); 252 } 253 254 /** 255 * RDF format for representing collections and arrays. 256 * 257 * <ul class='values'> 258 * <li><js>"DEFAULT"</js> - Default format. The default is an RDF Sequence container. 259 * <li><js>"SEQ"</js> - RDF Sequence container. 260 * <li><js>"BAG"</js> - RDF Bag container. 261 * <li><js>"LIST"</js> - RDF List container. 262 * <li><js>"MULTI_VALUED"</js> - Multi-valued properties. 263 * </ul> 264 * 265 * <h5 class='section'>Notes:</h5><ul> 266 * <li class='note'> 267 * If you use <js>"BAG"</js> or <js>"MULTI_VALUED"</js>, the order of the elements in the collection will get 268 * lost. 269 * </ul> 270 * 271 * @param value 272 * The new value for this setting. 273 * <br>Cannot be <jk>null</jk>. 274 * @return This object. 275 */ 276 public SELF collectionFormat(RdfCollectionFormat value) { 277 collectionFormat = reqnn("value", value); 278 return self(); 279 } 280 281 @Override /* Overridden from Context.Builder<?> */ 282 public abstract SELF copy(); 283 284 /** 285 * Disable auto-detect namespace usage. 286 * 287 * <p> 288 * Don't detect namespace usage before serialization. 289 * 290 * <p> 291 * If enabled, then the data structure will first be crawled looking for namespaces that will be encountered before 292 * the root element is serialized. 293 * 294 * @return This object. 295 */ 296 public SELF disableAutoDetectNamespaces() { 297 return disableAutoDetectNamespaces(true); 298 } 299 300 /** 301 * Disable auto-detect namespace usage. 302 * 303 * <p> 304 * Don't detect namespace usage before serialization. 305 * 306 * <p> 307 * If enabled, then the data structure will first be crawled looking for namespaces that will be encountered before 308 * the root element is serialized. 309 * 310 * @param value 311 * The new value for this setting. 312 * @return This object. 313 */ 314 public SELF disableAutoDetectNamespaces(boolean value) { 315 disableAutoDetectNamespaces = value; 316 return self(); 317 } 318 319 /** 320 * Disable reuse of XML namespaces when RDF namespaces not specified. 321 * 322 * <p> 323 * When enabled, namespaces defined using {@link XmlNs @XmlNs} and {@link Xml Xml} will not be 324 * inherited by the RDF serializers. 325 * Otherwise, namespaces will be defined using {@link RdfNs @RdfNs} and {@link Rdf @Rdf}. 326 * 327 * @return This object. 328 */ 329 public SELF disableUseXmlNamespaces() { 330 return disableUseXmlNamespaces(true); 331 } 332 333 /** 334 * Disable reuse of XML namespaces when RDF namespaces not specified. 335 * 336 * <p> 337 * When enabled, namespaces defined using {@link XmlNs @XmlNs} and {@link Xml Xml} will not be 338 * inherited by the RDF serializers. 339 * Otherwise, namespaces will be defined using {@link RdfNs @RdfNs} and {@link Rdf @Rdf}. 340 * 341 * @param value 342 * The new value for this setting. 343 * @return This object. 344 */ 345 public SELF disableUseXmlNamespaces(boolean value) { 346 disableUseXmlNamespaces = value; 347 return self(); 348 } 349 350 @Override /* Overridden from Context.Builder<?> */ 351 public HashKey hashKey() { 352 // @formatter:off 353 return HashKey.of( 354 super.hashKey(), 355 addBeanTypesRdf, 356 addLiteralTypes, 357 addRootProperty, 358 disableAutoDetectNamespaces, 359 disableUseXmlNamespaces, 360 looseCollections, 361 language, 362 collectionFormat, 363 juneauNs, 364 juneauBpNs, 365 namespaces, 366 jenaSettings 367 ); 368 // @formatter:on 369 } 370 371 /** 372 * Default XML namespace for bean properties. 373 * 374 * @param value 375 * The new value for this setting. 376 * <br>The default is <code>{j:<js>'http://www.apache.org/juneaubp/'</js>}</code>. 377 * <br>Cannot be <jk>null</jk>. 378 * @return This object. 379 */ 380 public SELF juneauBpNs(Namespace value) { 381 juneauBpNs = reqnn("value", value); 382 return self(); 383 } 384 385 /** 386 * XML namespace for Juneau properties. 387 * 388 * @param value 389 * The new value for this setting. 390 * <br>The default is <code>{j:<js>'http://www.apache.org/juneau/'</js>}</code>. 391 * <br>Cannot be <jk>null</jk>. 392 * @return This object. 393 */ 394 public SELF juneauNs(Namespace value) { 395 juneauNs = reqnn("value", value); 396 return self(); 397 } 398 399 /** 400 * RDF language. 401 * 402 * <p> 403 * Can be any of the following: 404 * <ul class='spaced-list'> 405 * <li> 406 * <js>"RDF/XML"</js> 407 * <li> 408 * <js>"RDF/XML-ABBREV"</js> (default) 409 * <li> 410 * <js>"N-TRIPLE"</js> 411 * <li> 412 * <js>"N3"</js> - General name for the N3 writer. 413 * Will make a decision on exactly which writer to use (pretty writer, plain writer or simple writer) when 414 * created. 415 * Default is the pretty writer but can be overridden with system property 416 * <c>org.apache.jena.n3.N3JenaWriter.writer</c>. 417 * <li> 418 * <js>"N3-PP"</js> - Name of the N3 pretty writer. 419 * The pretty writer uses a frame-like layout, with prefixing, clustering like properties and embedding 420 * one-referenced bNodes. 421 * <li> 422 * <js>"N3-PLAIN"</js> - Name of the N3 plain writer. 423 * The plain writer writes records by subject. 424 * <li> 425 * <js>"N3-TRIPLES"</js> - Name of the N3 triples writer. 426 * This writer writes one line per statement, like N-Triples, but does N3-style prefixing. 427 * <li> 428 * <js>"TURTLE"</js> - Turtle writer. 429 * http://www.dajobe.org/2004/01/turtle/ 430 * </ul> 431 * 432 * <h5 class='section'>See Also:</h5><ul> 433 * <li class='jm'>{@link #n3()} 434 * <li class='jm'>{@link #ntriple()} 435 * <li class='jm'>{@link #turtle()} 436 * <li class='jm'>{@link #xml()} 437 * <li class='jm'>{@link #xmlabbrev()} 438 * </ul> 439 * 440 * @param value 441 * The new value for this setting. 442 * <br>Cannot be <jk>null</jk>. 443 * @return This object. 444 */ 445 public SELF language(String value) { 446 language = reqnn("value", value); 447 return self(); 448 } 449 450 /** 451 * Collections should be serialized and parsed as loose collections. 452 * 453 * <p> 454 * When specified, collections of resources are handled as loose collections of resources in RDF instead of 455 * resources that are children of an RDF collection (e.g. Sequence, Bag). 456 * 457 * <p> 458 * Note that this setting is specialized for RDF syntax, and is incompatible with the concept of 459 * losslessly representing POJO models, since the tree structure of these POJO models are lost 460 * when serialized as loose collections. 461 * 462 * <p> 463 * This setting is typically only useful if the beans being parsed into do not have a bean property 464 * annotated with {@link Rdf#beanUri @Rdf(beanUri=true)}. 465 * 466 * <h5 class='section'>Example:</h5> 467 * <p class='bjava'> 468 * WriterSerializer <jv>serializer</jv> = RdfSerializer 469 * .<jsm>create</jsm>() 470 * .xmlabbrev() 471 * .looseCollections() 472 * .build(); 473 * 474 * ReaderParser <jv>parser</jv> = RdfParser 475 * .<jsm>create</jsm>() 476 * .xml() 477 * .looseCollections() 478 * .build(); 479 * 480 * List<MyBean> <jv>list</jv> = <jsm>createListOfMyBeans</jsm>(); 481 * 482 * <jc>// Serialize to RDF/XML as loose resources</jc> 483 * String <jv>rdfXml</jv> = <jv>serializer</jv>.write(<jv>list</jv>); 484 * 485 * <jc>// Parse back into a Java collection</jc> 486 * <jv>list</jv> = <jv>parser</jv>.read(<jv>rdfXml</jv>, LinkedList.<jk>class</jk>, MyBean.<jk>class</jk>); 487 * 488 * MyBean[] <jv>beans</jv> = <jsm>createArrayOfMyBeans</jsm>(); 489 * 490 * <jc>// Serialize to RDF/XML as loose resources</jc> 491 * <jv>rdfXml</jv> = <jv>serializer</jv>.write(<jv>beans</jv>); 492 * 493 * <jc>// Parse back into a bean array</jc> 494 * <jv>beans</jv> = <jv>parser</jv>.read(<jv>rdfXml</jv>, MyBean[].<jk>class</jk>); 495 * </p> 496 * 497 * @return This object. 498 */ 499 public SELF looseCollections() { 500 return looseCollections(true); 501 } 502 503 /** 504 * Collections should be serialized and parsed as loose collections. 505 * 506 * <p> 507 * When specified, collections of resources are handled as loose collections of resources in RDF instead of 508 * resources that are children of an RDF collection (e.g. Sequence, Bag). 509 * 510 * <p> 511 * Note that this setting is specialized for RDF syntax, and is incompatible with the concept of 512 * losslessly representing POJO models, since the tree structure of these POJO models are lost 513 * when serialized as loose collections. 514 * 515 * <p> 516 * This setting is typically only useful if the beans being parsed into do not have a bean property 517 * annotated with {@link Rdf#beanUri @Rdf(beanUri=true)}. 518 * 519 * <h5 class='section'>Example:</h5> 520 * <p class='bjava'> 521 * WriterSerializer <jv>serializer</jv> = RdfSerializer 522 * .<jsm>create</jsm>() 523 * .xmlabbrev() 524 * .looseCollections() 525 * .build(); 526 * 527 * ReaderParser <jv>parser</jv> = RdfParser 528 * .<jsm>create</jsm>() 529 * .xml() 530 * .looseCollections() 531 * .build(); 532 * 533 * List<MyBean> <jv>list</jv> = <jsm>createListOfMyBeans</jsm>(); 534 * 535 * <jc>// Serialize to RDF/XML as loose resources</jc> 536 * String <jv>rdfXml</jv> = <jv>serializer</jv>.write(<jv>list</jv>); 537 * 538 * <jc>// Parse back into a Java collection</jc> 539 * <jv>list</jv> = <jv>parser</jv>.read(<jv>rdfXml</jv>, LinkedList.<jk>class</jk>, MyBean.<jk>class</jk>); 540 * 541 * MyBean[] <jv>beans</jv> = <jsm>createArrayOfMyBeans</jsm>(); 542 * 543 * <jc>// Serialize to RDF/XML as loose resources</jc> 544 * <jv>rdfXml</jv> = <jv>serializer</jv>.write(<jv>beans</jv>); 545 * 546 * <jc>// Parse back into a bean array</jc> 547 * <jv>beans</jv> = <jv>parser</jv>.read(<jv>rdfXml</jv>, MyBean[].<jk>class</jk>); 548 * </p> 549 * 550 * @param value 551 * The new value for this setting. 552 * @return This object. 553 */ 554 public SELF looseCollections(boolean value) { 555 looseCollections = value; 556 return self(); 557 } 558 559 /** 560 * RDF language. 561 * 562 * <p> 563 * Shortcut for calling <code>language(<jsf>LANG_N3</jsf>)</code> 564 * 565 * @return This object. 566 */ 567 public SELF n3() { 568 return language(Constants.LANG_N3); 569 } 570 571 /** 572 * N3/Turtle property: <c>disableAbbrevBaseURI</c>. 573 * 574 * <p> 575 * Controls whether to use abbreviations <c><></c> or <c><#></c>. 576 * 577 * @return This object. 578 */ 579 public SELF n3_disableAbbrevBaseUri() { 580 return n3_disableAbbrevBaseUri(true); 581 } 582 583 /** 584 * N3/Turtle property: <c>disableAbbrevBaseURI</c>. 585 * 586 * <p> 587 * Controls whether to use abbreviations <c><></c> or <c><#></c>. 588 * 589 * @param value 590 * The new value for this setting. 591 * @return This object. 592 */ 593 public SELF n3_disableAbbrevBaseUri(boolean value) { 594 return jena("n3.disableAbbrevBaseUri", value); 595 } 596 597 /** 598 * N3/Turtle property: <c>disableObjectLists</c>. 599 * 600 * <p> 601 * Don't print object lists as comma separated lists. 602 * 603 * @return This object. 604 */ 605 public SELF n3_disableObjectLists() { 606 return n3_disableObjectLists(true); 607 } 608 609 /** 610 * N3/Turtle property: <c>disableObjectLists</c>. 611 * 612 * <p> 613 * Don't print object lists as comma separated lists. 614 * 615 * @param value 616 * The new value for this setting. 617 * @return This object. 618 */ 619 public SELF n3_disableObjectLists(boolean value) { 620 return jena("n3.disableObjectLists", value); 621 } 622 623 /** 624 * N3/Turtle property: <c>disableUseDoubles</c>. 625 * 626 * <p> 627 * Disallow the use of doubles as <c>123.456</c>. 628 * 629 * @return This object. 630 */ 631 public SELF n3_disableUseDoubles() { 632 return n3_disableUseDoubles(true); 633 } 634 635 /** 636 * N3/Turtle property: <c>disableUseDoubles</c>. 637 * 638 * <p> 639 * Disallow the use of doubles as <c>123.456</c>. 640 * 641 * @param value 642 * The new value for this setting. 643 * @return This object. 644 */ 645 public SELF n3_disableUseDoubles(boolean value) { 646 return jena("n3.disableUseDoubles", value); 647 } 648 649 /** 650 * N3/Turtle property: <c>disableUsePropertySymbols</c>. 651 * 652 * <p> 653 * Controls whether to use <c>a</c>, <c>=</c> and <c>=></c> in output 654 * 655 * @return This object. 656 */ 657 public SELF n3_disableUsePropertySymbols() { 658 return n3_disableUsePropertySymbols(true); 659 } 660 661 /** 662 * N3/Turtle property: <c>disableUsePropertySymbols</c>. 663 * 664 * <p> 665 * Controls whether to use <c>a</c>, <c>=</c> and <c>=></c> in output 666 * 667 * @param value 668 * The new value for this setting. 669 * @return This object. 670 */ 671 public SELF n3_disableUsePropertySymbols(boolean value) { 672 return jena("n3.disableUsePropertySymbols", value); 673 } 674 675 /** 676 * N3/Turtle property: <c>disableUseTripleQuotedStrings</c>. 677 * 678 * <p> 679 * Disallow the use of <c>"""</c> to delimit long strings. 680 * 681 * @return This object. 682 */ 683 public SELF n3_disableUseTripleQuotedStrings() { 684 return n3_disableUseTripleQuotedStrings(true); 685 } 686 687 /** 688 * N3/Turtle property: <c>disableUseTripleQuotedStrings</c>. 689 * 690 * <p> 691 * Disallow the use of <c>"""</c> to delimit long strings. 692 * 693 * @param value 694 * The new value for this setting. 695 * @return This object. 696 */ 697 public SELF n3_disableUseTripleQuotedStrings(boolean value) { 698 return jena("n3.disableUseTripleQuotedStrings", value); 699 } 700 701 /** 702 * N3/Turtle property: <c>indentProperty</c>. 703 * 704 * <p> 705 * Width to indent properties. 706 * 707 * @param value 708 * The new value for this setting. 709 * @return This object. 710 */ 711 public SELF n3_indentProperty(int value) { 712 return jena("n3.indentProperty", value); 713 } 714 715 /** 716 * N3/Turtle property: <c>minGap</c>. 717 * 718 * <p> 719 * Minimum gap between items on a line. 720 * 721 * @param value 722 * The new value for this setting. 723 * @return This object. 724 */ 725 public SELF n3_minGap(int value) { 726 return jena("n3.minGap", value); 727 } 728 729 /** 730 * N3/Turtle property: <c>propertyColumn</c>. 731 * 732 * <p> 733 * Width of the property column. 734 * 735 * @param value 736 * The new value for this setting. 737 * @return This object. 738 */ 739 public SELF n3_propertyColumn(int value) { 740 return jena("n3.propertyColumn", value); 741 } 742 743 /** 744 * N3/Turtle property: <c>subjectColumn</c>. 745 * 746 * <p> 747 * If the subject is shorter than this value, the first property may go on the same line. 748 * 749 * @param value 750 * The new value for this setting. 751 * @return This object. 752 */ 753 public SELF n3_subjectColumn(int value) { 754 return jena("n3.subjectColumn", value); 755 } 756 757 /** 758 * N3/Turtle property: <c>widePropertyLen</c>. 759 * 760 * <p> 761 * Width of the property column. 762 * Must be longer than <c>propertyColumn</c>. 763 * 764 * @param value 765 * The new value for this setting. 766 * @return This object. 767 */ 768 public SELF n3_widePropertyLen(int value) { 769 return jena("n3.widePropertyLen", value); 770 } 771 772 /** 773 * Default namespaces. 774 * 775 * <p> 776 * The default list of namespaces associated with this serializer. 777 * 778 * @param values The new value for this setting. 779 * <br>Cannot contain <jk>null</jk> values (will throw {@link IllegalArgumentException}). 780 * @return This object. 781 */ 782 public SELF namespaces(Namespace...values) { 783 reqnns("values", values); 784 namespaces = addAll(namespaces, values); 785 return self(); 786 } 787 788 /** 789 * RDF language. 790 * 791 * <p> 792 * Shortcut for calling <code>language(<jsf>LANG_NTRIPLE</jsf>)</code> 793 * 794 * @return This object. 795 */ 796 public SELF ntriple() { 797 return language(Constants.LANG_NTRIPLE); 798 } 799 800 /** 801 * RDF/XML property: <c>allowBadURIs</c>. 802 * 803 * <p> 804 * URIs in the graph are, by default, checked prior to serialization. 805 * 806 * @return This object. 807 */ 808 public SELF rdfxml_allowBadUris() { 809 return rdfxml_allowBadUris(true); 810 } 811 812 /** 813 * RDF/XML property: <c>allowBadURIs</c>. 814 * 815 * <p> 816 * URIs in the graph are, by default, checked prior to serialization. 817 * 818 * @param value 819 * The new value for this setting. 820 * @return This object. 821 */ 822 public SELF rdfxml_allowBadUris(boolean value) { 823 return jena("rdfXml.allowBadURIs", value); 824 } 825 826 /** 827 * RDF/XML property: <c>attributeQuoteChar</c>. 828 * 829 * <p> 830 * The XML attribute quote character. 831 * 832 * @param value 833 * The new value for this setting. 834 * @return This object. 835 */ 836 public SELF rdfxml_attributeQuoteChar(char value) { 837 return jena("rdfXml.attributeQuoteChar", value); 838 } 839 840 /** 841 * RDF/XML property: <c>blockRules</c>. 842 * 843 * <p> 844 * A list of <c>Resource</c> or a <c>String</c> being a comma separated list of fragment IDs from 845 * {doc http://www.w3.org/TR/rdf-syntax-grammar RDF Syntax Grammar} indicating grammar 846 * rules that will not be used. 847 * 848 * @param value 849 * The new value for this setting. 850 * @return This object. 851 */ 852 public SELF rdfxml_blockRules(String value) { 853 return jena("rdfXml.blockRules", value); 854 } 855 856 /** 857 * RDF/XML property: <c>disableShowDoctypeDeclaration</c>. 858 * 859 * <p> 860 * If disabled, an XML doctype declaration isn't included in the output. 861 * This declaration includes a <c>!ENTITY</c> declaration for each prefix mapping in the model, and any 862 * attribute value that starts with the URI of that mapping is written as starting with the corresponding entity 863 * invocation. 864 * 865 * @return This object. 866 */ 867 public SELF rdfxml_disableShowDoctypeDeclaration() { 868 return rdfxml_disableShowDoctypeDeclaration(true); 869 } 870 871 /** 872 * RDF/XML property: <c>disableShowDoctypeDeclaration</c>. 873 * 874 * <p> 875 * If disabled, an XML doctype declaration isn't included in the output. 876 * This declaration includes a <c>!ENTITY</c> declaration for each prefix mapping in the model, and any 877 * attribute value that starts with the URI of that mapping is written as starting with the corresponding entity 878 * invocation. 879 * 880 * @param value 881 * The new value for this setting. 882 * @return This object. 883 */ 884 public SELF rdfxml_disableShowDoctypeDeclaration(boolean value) { 885 return jena("rdfXml.disableShowDoctypeDeclaration", value); 886 } 887 888 /** 889 * RDF/XML ARP property: <c>error-mode</c>. 890 * 891 * <p> 892 * Sets ARP to look for RDF embedded within an enclosing XML document. 893 * 894 * <h5 class='section'>See Also:</h5><ul> 895 * <li> 896 * {doc ext.ARP/ARPOptions.html#setEmbedding(boolean) ARPOptions.setEmbedding(boolean)} 897 * </ul> 898 * 899 * @return This object. 900 */ 901 public SELF rdfxml_embedding() { 902 return rdfxml_embedding(true); 903 } 904 905 /** 906 * RDF/XML ARP property: <c>error-mode</c>. 907 * 908 * <p> 909 * Sets ARP to look for RDF embedded within an enclosing XML document. 910 * 911 * <h5 class='section'>See Also:</h5><ul> 912 * <li> 913 * {doc ext.ARP/ARPOptions.html#setEmbedding(boolean) ARPOptions.setEmbedding(boolean)} 914 * </ul> 915 * 916 * @param value 917 * The new value for this setting. 918 * @return This object. 919 */ 920 public SELF rdfxml_embedding(boolean value) { 921 return jena("rdfXml.embedding", value); 922 } 923 924 /** 925 * RDF/XML ARP property: <c>error-mode</c>. 926 * 927 * <p> 928 * This allows a coarse-grained approach to control of error handling. 929 * 930 * <ul class='values'> 931 * <li><js>"default"</js> 932 * <li><js>"lax"</js> 933 * <li><js>"strict"</js> 934 * <li><js>"strict-ignore"</js> 935 * <li><js>"strict-warning"</js> 936 * <li><js>"strict-error"</js> 937 * <li><js>"strict-fatal"</js> 938 * </ul> 939 * 940 * <h5 class='section'>See Also:</h5><ul> 941 * <li> 942 * {doc ext.ARP/ARPOptions.html#setDefaultErrorMode() ARPOptions.setDefaultErrorMode()} 943 * <li> 944 * {doc ext.ARP/ARPOptions.html#setLaxErrorMode() ARPOptions.setLaxErrorMode()} 945 * <li> 946 * {doc ext.ARP/ARPOptions.html#setStrictErrorMode() ARPOptions.setStrictErrorMode()} 947 * <li> 948 * {doc ext.ARP/ARPOptions.html#setStrictErrorMode(int) ARPOptions.setStrictErrorMode(int)} 949 * </ul> 950 * 951 * @param value 952 * The new value for this setting. 953 * @return This object. 954 */ 955 public SELF rdfxml_errorMode(String value) { 956 return jena("rdfXml.error-mode", value); 957 } 958 959 /** 960 * RDF/XML property: <c>iri_rules</c>. 961 * 962 * <p> 963 * Set the engine for checking and resolving. 964 * 965 * <ul class='values spaced-list'> 966 * <li> 967 * <js>"lax"</js> - The rules for RDF URI references only, which does permit spaces although the use of spaces 968 * is not good practice. 969 * <li> 970 * <js>"strict"</js> - Sets the IRI engine with rules for valid IRIs, XLink and RDF; it does not permit spaces 971 * in IRIs. 972 * <li> 973 * <js>"iri"</js> - Sets the IRI engine to IRI 974 * ({doc http://www.ietf.org/rfc/rfc3986.txt RFC 3986}, 975 * {doc http://www.ietf.org/rfc/rfc3987.txt RFC 3987}). 976 * </ul> 977 * 978 * @param value 979 * The new value for this setting. 980 * @return This object. 981 */ 982 public SELF rdfxml_iriRules(String value) { 983 return jena("rdfXml.iri-rules", value); 984 } 985 986 /** 987 * RDF/XML property: <c>longId</c>. 988 * 989 * <p> 990 * Whether to use long ID's for anon resources. 991 * Short ID's are easier to read, but can run out of memory on very large models. 992 * 993 * @return This object. 994 */ 995 public SELF rdfxml_longId() { 996 return rdfxml_longId(true); 997 } 998 999 /** 1000 * RDF/XML property: <c>longId</c>. 1001 * 1002 * <p> 1003 * Whether to use long ID's for anon resources. 1004 * Short ID's are easier to read, but can run out of memory on very large models. 1005 * 1006 * @param value 1007 * The new value for this setting. 1008 * @return This object. 1009 */ 1010 public SELF rdfxml_longId(boolean value) { 1011 return jena("rdfXml.longId", value); 1012 } 1013 1014 /** 1015 * RDF/XML property: <c>relativeURIs</c>. 1016 * 1017 * <p> 1018 * What sort of relative URIs should be used. 1019 * 1020 * <p> 1021 * A comma separate list of options: 1022 * <ul class='spaced-list'> 1023 * <li> 1024 * <js>"same-document"</js> - Same-document references (e.g. <js>""</js> or <js>"#foo"</js>) 1025 * <li> 1026 * <js>"network"</js> - Network paths (e.g. <js>"//example.org/foo"</js> omitting the URI scheme) 1027 * <li> 1028 * <js>"absolute"</js> - Absolute paths (e.g. <js>"/foo"</js> omitting the scheme and authority) 1029 * <li> 1030 * <js>"relative"</js> - Relative path not beginning in <js>"../"</js> 1031 * <li> 1032 * <js>"parent"</js> - Relative path beginning in <js>"../"</js> 1033 * <li> 1034 * <js>"grandparent"</js> - Relative path beginning in <js>"../../"</js> 1035 * </ul> 1036 * 1037 * <p> 1038 * The default value is <js>"same-document, absolute, relative, parent"</js>. 1039 * To switch off relative URIs use the value <js>""</js>. 1040 * Relative URIs of any of these types are output where possible if and only if the option has been specified. 1041 * 1042 * @param value 1043 * The new value for this setting. 1044 * @return This object. 1045 */ 1046 public SELF rdfxml_relativeUris(String value) { 1047 return jena("rdfXml.relativeURIs", value); 1048 } 1049 1050 /** 1051 * RDF/XML property: <c>showXmlDeclaration</c>. 1052 * 1053 * <ul class='values spaced-list'> 1054 * <li> 1055 * <js>"true"</js> - Add XML Declaration to the output. 1056 * <li> 1057 * <js>"false"</js> - Don't add XML Declaration to the output. 1058 * <li> 1059 * <js>"default"</js> - Only add an XML Declaration when asked to write to an <c>OutputStreamWriter</c> 1060 * that uses some encoding other than <c>UTF-8</c> or <c>UTF-16</c>. 1061 * In this case the encoding is shown in the XML declaration. 1062 * </ul> 1063 * 1064 * @param value 1065 * The new value for this setting. 1066 * @return This object. 1067 */ 1068 public SELF rdfxml_showXmlDeclaration(String value) { 1069 return jena("rdfXml.showXmlDeclaration", value); 1070 } 1071 1072 /** 1073 * RDF/XML property: <c>tab</c>. 1074 * 1075 * <p> 1076 * The number of spaces with which to indent XML child elements. 1077 * 1078 * @param value 1079 * The new value for this setting. 1080 * @return This object. 1081 */ 1082 public SELF rdfxml_tab(int value) { 1083 return jena("rdfXml.tab", value); 1084 } 1085 1086 /** 1087 * RDF/XML property: <c>xmlbase</c>. 1088 * 1089 * <p> 1090 * The value to be included for an <xa>xml:base</xa> attribute on the root element in the file. 1091 * 1092 * @param value 1093 * The new value for this setting. 1094 * @return This object. 1095 */ 1096 public SELF rdfxml_xmlbase(String value) { 1097 return jena("rdfXml.xmlbase", value); 1098 } 1099 1100 /** 1101 * RDF language. 1102 * 1103 * <p> 1104 * Shortcut for calling <code>language(<jsf>LANG_TURTLE</jsf>)</code> 1105 * 1106 * @return This object. 1107 */ 1108 public SELF turtle() { 1109 return language(Constants.LANG_TURTLE); 1110 } 1111 1112 /** 1113 * RDF language. 1114 * 1115 * <p> 1116 * Shortcut for calling <code>language(<jsf>LANG_JSONLD</jsf>)</code> 1117 * 1118 * @return This object. 1119 */ 1120 public SELF jsonLd() { 1121 return language(Constants.LANG_JSONLD); 1122 } 1123 1124 /** 1125 * RDF language. 1126 * 1127 * <p> 1128 * Shortcut for calling <code>language(<jsf>LANG_NQUADS</jsf>)</code> 1129 * 1130 * @return This object. 1131 */ 1132 public SELF nQuads() { 1133 return language(Constants.LANG_NQUADS); 1134 } 1135 1136 /** 1137 * RDF language. 1138 * 1139 * <p> 1140 * Shortcut for calling <code>language(<jsf>LANG_TRIG</jsf>)</code> 1141 * 1142 * @return This object. 1143 */ 1144 public SELF triG() { 1145 return language(Constants.LANG_TRIG); 1146 } 1147 1148 /** 1149 * RDF language. 1150 * 1151 * <p> 1152 * Shortcut for calling <code>language(<jsf>LANG_TRIX</jsf>)</code> 1153 * 1154 * @return This object. 1155 */ 1156 public SELF triX() { 1157 return language(Constants.LANG_TRIX); 1158 } 1159 1160 /** 1161 * RDF language. 1162 * 1163 * <p> 1164 * Shortcut for calling <code>language(<jsf>LANG_RDFJSON</jsf>)</code> 1165 * 1166 * @return This object. 1167 */ 1168 public SELF rdfJson() { 1169 return language(Constants.LANG_RDFJSON); 1170 } 1171 1172 1173 /** 1174 * RDF language. 1175 * 1176 * <p> 1177 * Shortcut for calling <code>language(<jsf>LANG_RDF_XML</jsf>)</code> 1178 * 1179 * @return This object. 1180 */ 1181 public SELF xml() { 1182 return language(Constants.LANG_RDF_XML); 1183 } 1184 1185 /** 1186 * RDF language. 1187 * 1188 * <p> 1189 * Shortcut for calling <code>language(<jsf>LANG_RDF_XML_ABBREV</jsf>)</code> 1190 * 1191 * @return This object. 1192 */ 1193 public SELF xmlabbrev() { 1194 return language(Constants.LANG_RDF_XML_ABBREV); 1195 } 1196 1197 SELF jena(String key, Object value) { 1198 jenaSettings.put(key, value); 1199 return self(); 1200 } 1201 } 1202 1203 /** 1204 * Concrete default builder leaf for the non-subclassed {@link RdfSerializer#create()} / {@link RdfSerializer#copy()} path. 1205 */ 1206 public static final class DefaultBuilder extends Builder<DefaultBuilder> { 1207 1208 DefaultBuilder() {} 1209 1210 DefaultBuilder(RdfSerializer copyFrom) { 1211 super(copyFrom); 1212 } 1213 1214 DefaultBuilder(Builder<?> copyFrom) { 1215 super(copyFrom); 1216 } 1217 1218 @Override /* Overridden from Context.Builder<?> */ 1219 public DefaultBuilder copy() { 1220 return new DefaultBuilder(this); 1221 } 1222 } 1223 1224 private static final Namespace[] EMPTY_NAMESPACE_ARRAY = new Namespace[0]; 1225 1226 /** 1227 * Creates a new builder for this object. 1228 * 1229 * @return A new builder. 1230 */ 1231 @SuppressWarnings({ 1232 "java:S1452", // Builder<?> wildcard return intentional; callers chain via fluent API without needing the concrete type 1233 "java:S9149" // Public Juneau DSL factory; hiding parent create() is intentional. 1234 }) 1235 public static Builder<?> create() { 1236 return new DefaultBuilder(); 1237 } 1238 1239 private static String getAccept(Builder<?> builder) { 1240 if (nn(builder.getAccept())) 1241 return builder.getAccept(); 1242 return switch (builder.language) { 1243 case "RDF/XML" -> "text/xml+rdf+abbrev"; 1244 case LANG_RDF_XML_ABBREV -> "text/xml+rdf+abbrev,text/xml+rdf;q=0.9"; 1245 case "N-TRIPLE" -> "text/n-triple"; 1246 case "N3" -> "text/n3"; 1247 case "N3-PP" -> "text/n3-pp"; 1248 case "N3-PLAIN" -> "text/n3-plain"; 1249 case "N3-TRIPLES" -> "text/n3-triples"; 1250 case "TURTLE" -> "text/turtle"; 1251 case "JSON-LD" -> "application/ld+json"; 1252 case "N-QUADS" -> "application/n-quads"; 1253 case "TRIG" -> "application/trig"; 1254 case "TRIX" -> "application/trix+xml"; 1255 case "RDF/JSON" -> "application/rdf+json"; 1256 default -> MT_TEXT_XML_RDF; 1257 }; 1258 } 1259 1260 private static String getProduces(Builder<?> builder) { 1261 if (nn(builder.getProduces())) 1262 return builder.getProduces(); 1263 return switch (builder.language) { 1264 case "RDF/XML" -> "text/xml+rdf+abbrev"; 1265 case LANG_RDF_XML_ABBREV -> MT_TEXT_XML_RDF; 1266 case "N-TRIPLE" -> "text/n-triple"; 1267 case "N3" -> "text/n3"; 1268 case "N3-PP" -> "text/n3-pp"; 1269 case "N3-PLAIN" -> "text/n3-plain"; 1270 case "N3-TRIPLES" -> "text/n3-triples"; 1271 case "TURTLE" -> "text/turtle"; 1272 case "JSON-LD" -> "application/ld+json"; 1273 case "N-QUADS" -> "application/n-quads"; 1274 case "TRIG" -> "application/trig"; 1275 case "TRIX" -> "application/trix+xml"; 1276 case "RDF/JSON" -> "application/rdf+json"; 1277 default -> MT_TEXT_XML_RDF; 1278 }; 1279 } 1280 1281 protected final boolean addBeanTypesRdf; 1282 protected final boolean addLiteralTypes; 1283 protected final boolean addRootProperty; 1284 protected final boolean autoDetectNamespaces; 1285 protected final boolean looseCollections; 1286 protected final boolean useXmlNamespaces; 1287 protected final Namespace juneauBpNs; 1288 protected final Namespace juneauNs; 1289 protected final RdfCollectionFormat collectionFormat; 1290 protected final String language; 1291 1292 final Map<String,Object> jenaSettings; 1293 final Namespace[] namespaces; 1294 private final boolean addBeanTypesEffective; 1295 private final Map<ClassMeta<?>,RdfClassMeta> rdfClassMetas = new ConcurrentHashMap<>(); 1296 1297 private final Map<BeanMeta<?>,RdfBeanMeta> rdfBeanMetas = new ConcurrentHashMap<>(); 1298 private final Map<BeanPropertyMeta,RdfBeanPropertyMeta> rdfBeanPropertyMetas = new ConcurrentHashMap<>(); 1299 private final Map<ClassMeta<?>,XmlClassMeta> xmlClassMetas = new ConcurrentHashMap<>(); 1300 1301 private final Map<BeanMeta<?>,XmlBeanMeta> xmlBeanMetas = new ConcurrentHashMap<>(); 1302 1303 private final Map<BeanPropertyMeta,XmlBeanPropertyMeta> xmlBeanPropertyMetas = new ConcurrentHashMap<>(); 1304 1305 /** 1306 * Constructor. 1307 * 1308 * @param builder 1309 * The builder for this object. 1310 * <br>Cannot be <jk>null</jk>. 1311 */ 1312 public RdfSerializer(Builder<?> builder) { 1313 super(builder.produces(getProduces(builder)).accept(getAccept(builder))); 1314 addLiteralTypes = builder.addLiteralTypes; 1315 addRootProperty = builder.addRootProperty; 1316 useXmlNamespaces = ! builder.disableUseXmlNamespaces; 1317 looseCollections = builder.looseCollections; 1318 autoDetectNamespaces = ! builder.disableAutoDetectNamespaces; 1319 language = builder.language; 1320 juneauNs = builder.juneauNs; 1321 juneauBpNs = builder.juneauBpNs; 1322 collectionFormat = builder.collectionFormat; 1323 namespaces = nn(builder.namespaces) ? builder.namespaces.toArray(EMPTY_NAMESPACE_ARRAY) : EMPTY_NAMESPACE_ARRAY; 1324 addBeanTypesRdf = builder.addBeanTypesRdf; 1325 jenaSettings = new TreeMap<>(builder.jenaSettings); 1326 1327 addBeanTypesEffective = addBeanTypesRdf || super.isAddBeanTypes(); 1328 } 1329 1330 @Override /* Overridden from Context */ 1331 public Builder<?> copy() { 1332 return new DefaultBuilder(this); 1333 } 1334 1335 @Override /* Overridden from Context */ 1336 public RdfSerializerSession.Builder createSession() { 1337 return RdfSerializerSession.create(this); 1338 } 1339 1340 /** 1341 * Default namespaces. 1342 * 1343 * @see RdfSerializer.Builder#namespaces(Namespace...) 1344 * @return 1345 * The default list of namespaces associated with this serializer. 1346 */ 1347 public Namespace[] getNamespaces() { return cp(namespaces); } 1348 1349 @Override /* Overridden from RdfMetaProvider */ 1350 public RdfBeanMeta getRdfBeanMeta(BeanMeta<?> bm) { 1351 return rdfBeanMetas.computeIfAbsent(bm, k -> new RdfBeanMeta(k, this)); 1352 } 1353 1354 @Override /* Overridden from RdfMetaProvider */ 1355 public RdfBeanPropertyMeta getRdfBeanPropertyMeta(BeanPropertyMeta bpm) { 1356 return rdfBeanPropertyMetas.computeIfAbsent(bpm, k -> new RdfBeanPropertyMeta(k.getDelegateFor(), this)); 1357 } 1358 1359 @Override /* Overridden from RdfMetaProvider */ 1360 public RdfClassMeta getRdfClassMeta(ClassMeta<?> cm) { 1361 return rdfClassMetas.computeIfAbsent(cm, k -> new RdfClassMeta(k, this)); 1362 } 1363 1364 @Override /* Overridden from Context */ 1365 public RdfSerializerSession getSession() { return createSession().build(); } 1366 1367 @Override /* Overridden from XmlMetaProvider */ 1368 public XmlBeanMeta getXmlBeanMeta(BeanMeta<?> bm) { 1369 return xmlBeanMetas.computeIfAbsent(bm, k -> new XmlBeanMeta(k, this)); 1370 } 1371 1372 @Override /* Overridden from XmlMetaProvider */ 1373 public XmlBeanPropertyMeta getXmlBeanPropertyMeta(BeanPropertyMeta bpm) { 1374 return xmlBeanPropertyMetas.computeIfAbsent(bpm, k -> new XmlBeanPropertyMeta(k.getDelegateFor(), this)); 1375 } 1376 1377 @Override /* Overridden from XmlMetaProvider */ 1378 public XmlClassMeta getXmlClassMeta(ClassMeta<?> cm) { 1379 return xmlClassMetas.computeIfAbsent(cm, k -> new XmlClassMeta(k, this)); 1380 } 1381 1382 /** 1383 * RDF format for representing collections and arrays. 1384 * 1385 * @see RdfSerializer.Builder#collectionFormat(RdfCollectionFormat) 1386 * @return 1387 * RDF format for representing collections and arrays. 1388 */ 1389 protected final RdfCollectionFormat getCollectionFormat() { return collectionFormat; } 1390 1391 /** 1392 * All Jena-related configuration properties. 1393 * 1394 * @return 1395 * A map of all Jena-related configuration properties. 1396 */ 1397 protected final Map<String,Object> getJenaSettings() { return u(jenaSettings); } 1398 1399 /** 1400 * Default XML namespace for bean properties. 1401 * 1402 * @see RdfSerializer.Builder#juneauBpNs(Namespace) 1403 * @return 1404 * The XML namespace to use for bean properties. 1405 */ 1406 protected final Namespace getJuneauBpNs() { return juneauBpNs; } 1407 1408 /** 1409 * XML namespace for Juneau properties. 1410 * 1411 * @see RdfSerializer.Builder#juneauNs(Namespace) 1412 * @return 1413 * The XML namespace to use for Juneau properties. 1414 */ 1415 protected final Namespace getJuneauNs() { return juneauNs; } 1416 1417 /** 1418 * RDF language. 1419 * 1420 * @see RdfSerializer.Builder#language(String) 1421 * @return 1422 * The RDF language to use. 1423 */ 1424 protected final String getLanguage() { return language; } 1425 1426 /** 1427 * Add <js>"_type"</js> properties when needed. 1428 * 1429 * @see RdfSerializer.Builder#addBeanTypes() 1430 * @return 1431 * <jk>true</jk> if <js>"_type"</js> properties will be added to beans if their type cannot be inferred 1432 * through reflection. 1433 */ 1434 @Override 1435 protected final boolean isAddBeanTypes() { return addBeanTypesEffective; } 1436 1437 /** 1438 * Add XSI data types to non-<c>String</c> literals. 1439 * 1440 * @see RdfSerializer.Builder#addLiteralTypes() 1441 * @return 1442 * <jk>true</jk> if XSI data types should be added to string literals. 1443 */ 1444 protected final boolean isAddLiteralTypes() { return addLiteralTypes; } 1445 1446 /** 1447 * Add RDF root identifier property to root node. 1448 * 1449 * @see RdfSerializer.Builder#addRootProperty() 1450 * @return 1451 * <jk>true</jk> if RDF property <c>http://www.apache.org/juneau/root</c> is added with a value of <js>"true"</js> 1452 * to identify the root node in the graph. 1453 */ 1454 protected final boolean isAddRootProp() { return addRootProperty; } 1455 1456 /** 1457 * Auto-detect namespace usage. 1458 * 1459 * @see RdfSerializer.Builder#disableAutoDetectNamespaces() 1460 * @return 1461 * <jk>true</jk> if namespaces usage should be detected before serialization. 1462 */ 1463 protected final boolean isAutoDetectNamespaces() { return autoDetectNamespaces; } 1464 1465 /** 1466 * Collections should be serialized and parsed as loose collections. 1467 * 1468 * @see RdfSerializer.Builder#looseCollections() 1469 * @return 1470 * <jk>true</jk> if collections of resources are handled as loose collections of resources in RDF instead of 1471 * resources that are children of an RDF collection (e.g. Sequence, Bag). 1472 */ 1473 protected final boolean isLooseCollections() { return looseCollections; } 1474 1475 /** 1476 * Reuse XML namespaces when RDF namespaces not specified. 1477 * 1478 * @see RdfSerializer.Builder#disableUseXmlNamespaces() 1479 * @return 1480 * <jk>true</jk> if namespaces defined using {@link XmlNs @XmlNs} and {@link Xml @Xml} will be inherited by the RDF serializers. 1481 * <br>Otherwise, namespaces will be defined using {@link RdfNs @RdfNs} and {@link Rdf @Rdf}. 1482 */ 1483 protected final boolean isUseXmlNamespaces() { return useXmlNamespaces; } 1484 1485 @Override /* Overridden from WriterSerializer */ 1486 protected FluentMap<String,Object> properties() { 1487 return super.properties() 1488 .a("addBeanTypes", addBeanTypes) 1489 .a("addLiteralTypes", addLiteralTypes) 1490 .a("addRootProperty", addRootProperty) 1491 .a("autoDetectNamespaces", autoDetectNamespaces) 1492 .a("collectionFormat", collectionFormat) 1493 .a("juneauBpNs", juneauBpNs) 1494 .a("juneauNs", juneauNs) 1495 .a("language", language) 1496 .a("looseCollections", looseCollections) 1497 .a("namespaces", namespaces) 1498 .a("useXmlNamespaces", useXmlNamespaces); 1499 } 1500}