001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.jena; 014 015import static org.apache.juneau.internal.CollectionUtils.*; 016 017import java.util.*; 018import java.util.concurrent.*; 019 020import org.apache.juneau.*; 021import org.apache.juneau.annotation.*; 022import org.apache.juneau.jena.annotation.*; 023import org.apache.juneau.serializer.*; 024import org.apache.juneau.xml.*; 025import org.apache.juneau.xml.annotation.*; 026 027/** 028 * Serializes POJOs to RDF. 029 * 030 * <h5 class='topic'>Behavior-specific subclasses</h5> 031 * 032 * The following direct subclasses are provided for language-specific serializers: 033 * <ul> 034 * <li>{@link RdfXmlSerializer} - RDF/XML. 035 * <li>{@link RdfXmlAbbrevSerializer} - RDF/XML-ABBREV. 036 * <li>{@link NTripleSerializer} - N-TRIPLE. 037 * <li>{@link TurtleSerializer} - TURTLE. 038 * <li>{@link N3Serializer} - N3. 039 * </ul> 040 * 041 * <ul class='seealso'> 042 * <li class='link'>{@doc juneau-marshall-rdf} 043 * </ul> 044 */ 045@ConfigurableContext(prefixes={RdfCommon.PREFIX,RdfSerializer.PREFIX}) 046public class RdfSerializer extends WriterSerializer implements RdfCommon, RdfMetaProvider { 047 048 private static final Namespace 049 DEFAULT_JUNEAU_NS = Namespace.create("j", "http://www.apache.org/juneau/"), 050 DEFAULT_JUNEAUBP_NS = Namespace.create("jp", "http://www.apache.org/juneaubp/"); 051 052 //------------------------------------------------------------------------------------------------------------------- 053 // Configurable properties 054 //------------------------------------------------------------------------------------------------------------------- 055 056 static final String PREFIX = "RdfSerializer"; 057 058 /** 059 * Configuration property: Add <js>"_type"</js> properties when needed. 060 * 061 * <h5 class='section'>Property:</h5> 062 * <ul class='spaced-list'> 063 * <li><b>ID:</b> {@link org.apache.juneau.jena.RdfSerializer#RDF_addBeanTypes RDF_addBeanTypes} 064 * <li><b>Name:</b> <js>"RdfSerializer.addBeanTypes.b"</js> 065 * <li><b>Data type:</b> <jk>boolean</jk> 066 * <li><b>System property:</b> <c>RdfSerializer.addBeanTypes</c> 067 * <li><b>Environment variable:</b> <c>RDFSERIALIZER_ADDBEANTYPES</c> 068 * <li><b>Default:</b> <jk>false</jk> 069 * <li><b>Session property:</b> <jk>false</jk> 070 * <li><b>Annotations:</b> 071 * <ul> 072 * <li class='ja'>{@link org.apache.juneau.jena.annotation.RdfConfig#addBeanTypes()} 073 * </ul> 074 * <li><b>Methods:</b> 075 * <ul> 076 * <li class='jm'>{@link org.apache.juneau.jena.RdfSerializerBuilder#addBeanTypes(boolean)} 077 * </ul> 078 * </ul> 079 * 080 * <h5 class='section'>Description:</h5> 081 * <p> 082 * If <jk>true</jk>, then <js>"_type"</js> properties will be added to beans if their type cannot be inferred 083 * through reflection. 084 * 085 * <p> 086 * When present, this value overrides the {@link #SERIALIZER_addBeanTypes} setting and is 087 * provided to customize the behavior of specific serializers in a {@link SerializerGroup}. 088 */ 089 public static final String RDF_addBeanTypes = PREFIX + ".addBeanTypes.b"; 090 091 /** 092 * Configuration property: Add XSI data types to non-<c>String</c> literals. 093 * 094 * <h5 class='section'>Property:</h5> 095 * <ul class='spaced-list'> 096 * <li><b>ID:</b> {@link org.apache.juneau.jena.RdfSerializer#RDF_addLiteralTypes RDF_addLiteralTypes} 097 * <li><b>Name:</b> <js>"RdfSerializer.addLiteralTypes.b"</js> 098 * <li><b>Data type:</b> <jk>boolean</jk> 099 * <li><b>System property:</b> <c>RdfSerializer.addLiteralTypes</c> 100 * <li><b>Environment variable:</b> <c>RDFSERIALIZER_ADDLITERALTYPES</c> 101 * <li><b>Default:</b> <jk>false</jk> 102 * <li><b>Session property:</b> <jk>false</jk> 103 * <li><b>Annotations:</b> 104 * <ul> 105 * <li class='ja'>{@link org.apache.juneau.jena.annotation.RdfConfig#addLiteralTypes()} 106 * </ul> 107 * <li><b>Methods:</b> 108 * <ul> 109 * <li class='jm'>{@link org.apache.juneau.jena.RdfSerializerBuilder#addLiteralTypes(boolean)} 110 * <li class='jm'>{@link org.apache.juneau.jena.RdfSerializerBuilder#addLiteralTypes()} 111 * </ul> 112 * </ul> 113 */ 114 public static final String RDF_addLiteralTypes = PREFIX + ".addLiteralTypes.b"; 115 116 /** 117 * Configuration property: Add RDF root identifier property to root node. 118 * 119 * <h5 class='section'>Property:</h5> 120 * <ul class='spaced-list'> 121 * <li><b>ID:</b> {@link org.apache.juneau.jena.RdfSerializer#RDF_addRootProperty RDF_addRootProperty} 122 * <li><b>Name:</b> <js>"RdfSerializer.addRootProperty.b"</js> 123 * <li><b>Data type:</b> <jk>boolean</jk> 124 * <li><b>System property:</b> <c>RdfSerializer.addRootProperty</c> 125 * <li><b>Environment variable:</b> <c>RDFSERIALIZER_ADDROOTPROPERTY</c> 126 * <li><b>Default:</b> <jk>false</jk> 127 * <li><b>Session property:</b> <jk>false</jk> 128 * <li><b>Annotations:</b> 129 * <ul> 130 * <li class='ja'>{@link org.apache.juneau.jena.annotation.RdfConfig#addRootProperty()} 131 * </ul> 132 * <li><b>Methods:</b> 133 * <ul> 134 * <li class='jm'>{@link org.apache.juneau.jena.RdfSerializerBuilder#addRootProperty(boolean)} 135 * <li class='jm'>{@link org.apache.juneau.jena.RdfSerializerBuilder#addRootProperty()} 136 * </ul> 137 * </ul> 138 * 139 * <h5 class='section'>Description:</h5> 140 * <p> 141 * When enabled an RDF property <c>http://www.apache.org/juneau/root</c> is added with a value of <js>"true"</js> 142 * to identify the root node in the graph. 143 * <br>This helps locate the root node during parsing. 144 * 145 * <p> 146 * If disabled, the parser has to search through the model to find any resources without incoming predicates to 147 * identify root notes, which can introduce a considerable performance degradation. 148 */ 149 public static final String RDF_addRootProperty = PREFIX + ".addRootProperty.b"; 150 151 /** 152 * Configuration property: Auto-detect namespace usage. 153 * 154 * <h5 class='section'>Property:</h5> 155 * <ul class='spaced-list'> 156 * <li><b>ID:</b> {@link org.apache.juneau.jena.RdfSerializer#RDF_autoDetectNamespaces RDF_autoDetectNamespaces} 157 * <li><b>Name:</b> <js>"RdfSerializer.autoDetectNamespaces.b"</js> 158 * <li><b>Data type:</b> <jk>boolean</jk> 159 * <li><b>System property:</b> <c>RdfSerializer.autoDetectNamespaces</c> 160 * <li><b>Environment variable:</b> <c>RDFSERIALIZER_AUTODETECTNAMESPACES</c> 161 * <li><b>Default:</b> <jk>true</jk> 162 * <li><b>Session property:</b> <jk>false</jk> 163 * <li><b>Annotations:</b> 164 * <ul> 165 * <li class='ja'>{@link org.apache.juneau.jena.annotation.RdfConfig#autoDetectNamespaces()} 166 * </ul> 167 * <li><b>Methods:</b> 168 * <ul> 169 * <li class='jm'>{@link org.apache.juneau.jena.RdfSerializerBuilder#autoDetectNamespaces(boolean)} 170 * </ul> 171 * </ul> 172 * 173 * <h5 class='section'>Description:</h5> 174 * <p> 175 * Detect namespace usage before serialization. 176 * 177 * <p> 178 * If enabled, then the data structure will first be crawled looking for namespaces that will be encountered before 179 * the root element is serialized. 180 */ 181 public static final String RDF_autoDetectNamespaces = PREFIX + ".autoDetectNamespaces.b"; 182 183 /** 184 * Configuration property: Default namespaces. 185 * 186 * <h5 class='section'>Property:</h5> 187 * <ul class='spaced-list'> 188 * <li><b>ID:</b> {@link org.apache.juneau.jena.RdfSerializer#RDF_namespaces RDF_namespaces} 189 * <li><b>Name:</b> <js>"RdfSerializer.namespaces.ls"</js> 190 * <li><b>Data type:</b> <c>List<{@link org.apache.juneau.xml.Namespace}></c> 191 * <li><b>System property:</b> <c>RdfSerializer.namespaces</c> 192 * <li><b>Environment variable:</b> <c>RDFSERIALIZER_NAMESPACES</c> 193 * <li><b>Default:</b> empty list 194 * <li><b>Session property:</b> <jk>false</jk> 195 * <li><b>Annotations:</b> 196 * <ul> 197 * <li class='ja'>{@link org.apache.juneau.jena.annotation.Rdf#namespace()} 198 * <li class='ja'>{@link org.apache.juneau.jena.annotation.RdfConfig#namespaces()} 199 * </ul> 200 * <li><b>Methods:</b> 201 * <ul> 202 * <li class='jm'>{@link org.apache.juneau.jena.RdfSerializerBuilder#namespaces(Namespace...)} 203 * </ul> 204 * </ul> 205 * 206 * <h5 class='section'>Description:</h5> 207 * <p> 208 * The default list of namespaces associated with this serializer. 209 */ 210 public static final String RDF_namespaces = PREFIX + ".namespaces.ls"; 211 212 /** 213 * Configuration property: Reuse XML namespaces when RDF namespaces not specified. 214 * 215 * <h5 class='section'>Property:</h5> 216 * <ul class='spaced-list'> 217 * <li><b>ID:</b> {@link org.apache.juneau.jena.RdfSerializer#RDF_useXmlNamespaces RDF_useXmlNamespaces} 218 * <li><b>Name:</b> <js>"Rdf.useXmlNamespaces.b"</js> 219 * <li><b>Data type:</b> <jk>boolean</jk> 220 * <li><b>System property:</b> <c>Rdf.useXmlNamespaces</c> 221 * <li><b>Environment variable:</b> <c>RDFSERIALIZER_USEXMLNAMESPACES</c> 222 * <li><b>Default:</b> <jk>true</jk> 223 * <li><b>Annotations:</b> 224 * <ul> 225 * <li class='ja'>{@link org.apache.juneau.jena.annotation.RdfConfig#useXmlNamespaces()} 226 * </ul> 227 * <li><b>Methods:</b> 228 * <ul> 229 * <li class='jm'>{@link org.apache.juneau.jena.RdfSerializerBuilder#useXmlNamespaces(boolean)} 230 * </ul> 231 * </ul> 232 * 233 * <h5 class='section'>Description:</h5> 234 * <p> 235 * When specified, namespaces defined using {@link XmlNs @XmlNs} and {@link Xml @Xml} will be inherited by the RDF serializers. 236 * <br>Otherwise, namespaces will be defined using {@link RdfNs @RdfNs} and {@link Rdf @Rdf}. 237 */ 238 public static final String RDF_useXmlNamespaces = PREFIX + ".useXmlNamespaces.b"; 239 240 //------------------------------------------------------------------------------------------------------------------- 241 // Instance 242 //------------------------------------------------------------------------------------------------------------------- 243 244 private final boolean 245 addLiteralTypes, 246 addRootProperty, 247 useXmlNamespaces, 248 looseCollections, 249 autoDetectNamespaces, 250 addBeanTypes; 251 private final String rdfLanguage; 252 private final Namespace juneauNs; 253 private final Namespace juneauBpNs; 254 private final RdfCollectionFormat collectionFormat; 255 final Map<String,Object> jenaProperties; 256 final Namespace[] namespaces; 257 258 private final Map<ClassMeta<?>,RdfClassMeta> rdfClassMetas = new ConcurrentHashMap<>(); 259 private final Map<BeanMeta<?>,RdfBeanMeta> rdfBeanMetas = new ConcurrentHashMap<>(); 260 private final Map<BeanPropertyMeta,RdfBeanPropertyMeta> rdfBeanPropertyMetas = new ConcurrentHashMap<>(); 261 262 private final Map<ClassMeta<?>,XmlClassMeta> xmlClassMetas = new ConcurrentHashMap<>(); 263 private final Map<BeanMeta<?>,XmlBeanMeta> xmlBeanMetas = new ConcurrentHashMap<>(); 264 private final Map<BeanPropertyMeta,XmlBeanPropertyMeta> xmlBeanPropertyMetas = new ConcurrentHashMap<>(); 265 266 /** 267 * Constructor. 268 * 269 * @param ps 270 * The property store containing all the settings for this object. 271 * @param produces 272 * The media type that this serializer produces. 273 * @param accept 274 * The accept media types that the serializer can handle. 275 * <p> 276 * Can contain meta-characters per the <c>media-type</c> specification of {@doc RFC2616.section14.1} 277 * <p> 278 * If empty, then assumes the only media type supported is <c>produces</c>. 279 * <p> 280 * For example, if this serializer produces <js>"application/json"</js> but should handle media types of 281 * <js>"application/json"</js> and <js>"text/json"</js>, then the arguments should be: 282 * <p class='bcode w800'> 283 * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json,text/json"</js>); 284 * </p> 285 * <br>...or... 286 * <p class='bcode w800'> 287 * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"*​/json"</js>); 288 * </p> 289 * <p> 290 * The accept value can also contain q-values. 291 */ 292 public RdfSerializer(PropertyStore ps, String produces, String accept) { 293 super(ps, produces, accept); 294 addLiteralTypes = getBooleanProperty(RDF_addLiteralTypes, false); 295 addRootProperty = getBooleanProperty(RDF_addRootProperty, false); 296 useXmlNamespaces = getBooleanProperty(RDF_useXmlNamespaces, true); 297 looseCollections = getBooleanProperty(RDF_looseCollections, false); 298 autoDetectNamespaces = getBooleanProperty(RDF_autoDetectNamespaces, true); 299 rdfLanguage = getStringProperty(RDF_language, "RDF/XML-ABBREV"); 300 juneauNs = getProperty(RDF_juneauNs, Namespace.class, DEFAULT_JUNEAU_NS); 301 juneauBpNs = getProperty(RDF_juneauBpNs, Namespace.class, DEFAULT_JUNEAUBP_NS); 302 collectionFormat = getProperty(RDF_collectionFormat, RdfCollectionFormat.class, RdfCollectionFormat.DEFAULT); 303 namespaces = getProperty(RDF_namespaces, Namespace[].class, new Namespace[0]); 304 addBeanTypes = getBooleanProperty(RDF_addBeanTypes, getBooleanProperty(SERIALIZER_addBeanTypes, false)); 305 306 Map<String,Object> m = new TreeMap<>(); 307 for (String k : getPropertyKeys("RdfCommon")) 308 if (k.startsWith("jena.")) 309 m.put(k.substring(5), getProperty("RdfCommon." + k)); 310 jenaProperties = unmodifiableMap(m); 311 } 312 313 /** 314 * Constructor. 315 * 316 * @param ps 317 * The property store containing all the settings for this object. 318 */ 319 public RdfSerializer(PropertyStore ps) { 320 this(ps, "text/xml+rdf", (String)null); 321 } 322 323 324 @Override /* Context */ 325 public RdfSerializerBuilder builder() { 326 return new RdfSerializerBuilder(getPropertyStore()); 327 } 328 329 /** 330 * Instantiates a new clean-slate {@link RdfSerializerBuilder} object. 331 * 332 * <p> 333 * This is equivalent to simply calling <code><jk>new</jk> RdfSerializerBuilder()</code>. 334 * 335 * <p> 336 * Note that this method creates a builder initialized to all default settings, whereas {@link #builder()} copies 337 * the settings of the object called on. 338 * 339 * @return A new {@link RdfSerializerBuilder} object. 340 */ 341 public static RdfSerializerBuilder create() { 342 return new RdfSerializerBuilder(); 343 } 344 345 @Override /* Context */ 346 public RdfSerializerSession createSession() { 347 return createSession(createDefaultSessionArgs()); 348 } 349 350 @Override /* Serializer */ 351 public RdfSerializerSession createSession(SerializerSessionArgs args) { 352 return new RdfSerializerSession(this, args); 353 } 354 355 //----------------------------------------------------------------------------------------------------------------- 356 // Extended metadata 357 //----------------------------------------------------------------------------------------------------------------- 358 359 @Override /* RdfMetaProvider */ 360 public RdfClassMeta getRdfClassMeta(ClassMeta<?> cm) { 361 RdfClassMeta m = rdfClassMetas.get(cm); 362 if (m == null) { 363 m = new RdfClassMeta(cm, this); 364 rdfClassMetas.put(cm, m); 365 } 366 return m; 367 } 368 369 @Override /* RdfMetaProvider */ 370 public RdfBeanMeta getRdfBeanMeta(BeanMeta<?> bm) { 371 RdfBeanMeta m = rdfBeanMetas.get(bm); 372 if (m == null) { 373 m = new RdfBeanMeta(bm, this); 374 rdfBeanMetas.put(bm, m); 375 } 376 return m; 377 } 378 379 @Override /* RdfMetaProvider */ 380 public RdfBeanPropertyMeta getRdfBeanPropertyMeta(BeanPropertyMeta bpm) { 381 RdfBeanPropertyMeta m = rdfBeanPropertyMetas.get(bpm); 382 if (m == null) { 383 m = new RdfBeanPropertyMeta(bpm.getDelegateFor(), this); 384 rdfBeanPropertyMetas.put(bpm, m); 385 } 386 return m; 387 } 388 389 @Override /* XmlMetaProvider */ 390 public XmlClassMeta getXmlClassMeta(ClassMeta<?> cm) { 391 XmlClassMeta m = xmlClassMetas.get(cm); 392 if (m == null) { 393 m = new XmlClassMeta(cm, this); 394 xmlClassMetas.put(cm, m); 395 } 396 return m; 397 } 398 399 @Override /* XmlMetaProvider */ 400 public XmlBeanMeta getXmlBeanMeta(BeanMeta<?> bm) { 401 XmlBeanMeta m = xmlBeanMetas.get(bm); 402 if (m == null) { 403 m = new XmlBeanMeta(bm, this); 404 xmlBeanMetas.put(bm, m); 405 } 406 return m; 407 } 408 409 @Override /* XmlMetaProvider */ 410 public XmlBeanPropertyMeta getXmlBeanPropertyMeta(BeanPropertyMeta bpm) { 411 XmlBeanPropertyMeta m = xmlBeanPropertyMetas.get(bpm); 412 if (m == null) { 413 m = new XmlBeanPropertyMeta(bpm.getDelegateFor(), this); 414 xmlBeanPropertyMetas.put(bpm, m); 415 } 416 return m; 417 } 418 419 //----------------------------------------------------------------------------------------------------------------- 420 // Common properties 421 //----------------------------------------------------------------------------------------------------------------- 422 423 /** 424 * Configuration property: RDF format for representing collections and arrays. 425 * 426 * @see #RDF_collectionFormat 427 * @return 428 * RDF format for representing collections and arrays. 429 */ 430 protected final RdfCollectionFormat getCollectionFormat() { 431 return collectionFormat; 432 } 433 434 /** 435 * Configuration property: Default XML namespace for bean properties. 436 * 437 * @see #RDF_juneauBpNs 438 * @return 439 * The XML namespace to use for bean properties. 440 */ 441 protected final Namespace getJuneauBpNs() { 442 return juneauBpNs; 443 } 444 445 /** 446 * Configuration property: XML namespace for Juneau properties. 447 * 448 * @see #RDF_juneauNs 449 * @return 450 * The XML namespace to use for Juneau properties. 451 */ 452 protected final Namespace getJuneauNs() { 453 return juneauNs; 454 } 455 456 /** 457 * Configuration property: RDF language. 458 * 459 * @see #RDF_language 460 * @return 461 * The RDF language to use. 462 */ 463 protected final String getLanguage() { 464 return rdfLanguage; 465 } 466 467 /** 468 * Configuration property: Collections should be serialized and parsed as loose collections. 469 * 470 * @see #RDF_looseCollections 471 * @return 472 * <jk>true</jk> if collections of resources are handled as loose collections of resources in RDF instead of 473 * resources that are children of an RDF collection (e.g. Sequence, Bag). 474 */ 475 protected final boolean isLooseCollections() { 476 return looseCollections; 477 } 478 479 //----------------------------------------------------------------------------------------------------------------- 480 // Jena properties 481 //----------------------------------------------------------------------------------------------------------------- 482 483 /** 484 * Configuration property: All Jena-related configuration properties. 485 * 486 * @return 487 * A map of all Jena-related configuration properties. 488 */ 489 protected final Map<String,Object> getJenaProperties() { 490 return jenaProperties; 491 } 492 493 //----------------------------------------------------------------------------------------------------------------- 494 // Properties 495 //----------------------------------------------------------------------------------------------------------------- 496 497 /** 498 * Configuration property: Add <js>"_type"</js> properties when needed. 499 * 500 * @see #RDF_addBeanTypes 501 * @return 502 * <jk>true</jk> if <js>"_type"</js> properties will be added to beans if their type cannot be inferred 503 * through reflection. 504 */ 505 @Override 506 protected final boolean isAddBeanTypes() { 507 return addBeanTypes; 508 } 509 510 /** 511 * Configuration property: Add XSI data types to non-<c>String</c> literals. 512 * 513 * @see #RDF_addLiteralTypes 514 * @return 515 * <jk>true</jk> if XSI data types should be added to string literals. 516 */ 517 protected final boolean isAddLiteralTypes() { 518 return addLiteralTypes; 519 } 520 521 /** 522 * Configuration property: Add RDF root identifier property to root node. 523 * 524 * @see RdfSerializer#RDF_addRootProperty 525 * @return 526 * <jk>true</jk> if RDF property <c>http://www.apache.org/juneau/root</c> is added with a value of <js>"true"</js> 527 * to identify the root node in the graph. 528 */ 529 protected final boolean isAddRootProp() { 530 return addRootProperty; 531 } 532 533 /** 534 * Configuration property: Auto-detect namespace usage. 535 * 536 * @see #RDF_autoDetectNamespaces 537 * @return 538 * <jk>true</jk> if namespaces usage should be detected before serialization. 539 */ 540 protected final boolean isAutoDetectNamespaces() { 541 return autoDetectNamespaces; 542 } 543 544 /** 545 * Configuration property: Default namespaces. 546 * 547 * @see #RDF_namespaces 548 * @return 549 * The default list of namespaces associated with this serializer. 550 */ 551 public Namespace[] getNamespaces() { 552 return namespaces; 553 } 554 555 /** 556 * Configuration property: Reuse XML namespaces when RDF namespaces not specified. 557 * 558 * @see #RDF_useXmlNamespaces 559 * @return 560 * <jk>true</jk> if namespaces defined using {@link XmlNs @XmlNs} and {@link Xml @Xml} will be inherited by the RDF serializers. 561 * <br>Otherwise, namespaces will be defined using {@link RdfNs @RdfNs} and {@link Rdf @Rdf}. 562 */ 563 protected final boolean isUseXmlNamespaces() { 564 return useXmlNamespaces; 565 } 566 567 //----------------------------------------------------------------------------------------------------------------- 568 // Other methods 569 //----------------------------------------------------------------------------------------------------------------- 570 571 @Override /* Context */ 572 public ObjectMap toMap() { 573 return super.toMap() 574 .append("RdfSerializer", new DefaultFilteringObjectMap() 575 .append("addLiteralTypes", addLiteralTypes) 576 .append("addRootProperty", addRootProperty) 577 .append("useXmlNamespaces", useXmlNamespaces) 578 .append("looseCollections", looseCollections) 579 .append("autoDetectNamespaces", autoDetectNamespaces) 580 .append("rdfLanguage", rdfLanguage) 581 .append("juneauNs", juneauNs) 582 .append("juneauBpNs", juneauBpNs) 583 .append("collectionFormat", collectionFormat) 584 .append("namespaces", namespaces) 585 .append("addBeanTypes", addBeanTypes) 586 ); 587 } 588}