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.serializer; 014 015import org.apache.juneau.*; 016import org.apache.juneau.utils.*; 017 018/** 019 * Subclass of {@link Serializer} for character-based serializers. 020 */ 021public abstract class WriterSerializer extends Serializer { 022 023 //------------------------------------------------------------------------------------------------------------------- 024 // Configurable properties 025 //------------------------------------------------------------------------------------------------------------------- 026 027 private static final String PREFIX = "WriterSerializer."; 028 029 /** 030 * Configuration property: Maximum indentation. 031 * 032 * <h5 class='section'>Property:</h5> 033 * <ul> 034 * <li><b>Name:</b> <js>"WriterSerializer.maxIndent.i"</js> 035 * <li><b>Data type:</b> <code>Integer</code> 036 * <li><b>Default:</b> <code>100</code> 037 * <li><b>Session property:</b> <jk>false</jk> 038 * <li><b>Methods:</b> 039 * <ul> 040 * <li class='jm'>{@link WriterSerializerBuilder#maxIndent(int)} 041 * </ul> 042 * </ul> 043 * 044 * <h5 class='section'>Description:</h5> 045 * <p> 046 * Specifies the maximum indentation level in the serialized document. 047 * 048 * <p> 049 * This setting does not apply to the RDF serializers. 050 * 051 * <h5 class='section'>Example:</h5> 052 * <p class='bcode w800'> 053 * <jc>// Create a serializer that indents a maximum of 20 tabs.</jc> 054 * WriterSerializer s = JsonSerializer 055 * .<jsm>create</jsm>() 056 * .maxIndent(20) 057 * .build(); 058 * 059 * <jc>// Same, but use property.</jc> 060 * WriterSerializer s = JsonSerializer 061 * .<jsm>create</jsm>() 062 * .set(<jsf>SERIALIZER_maxIndent</jsf>, 20) 063 * .build(); 064 * </p> 065 */ 066 public static final String WSERIALIZER_maxIndent = PREFIX + "maxIndent.i"; 067 068 /** 069 * Configuration property: Quote character. 070 * 071 * <h5 class='section'>Property:</h5> 072 * <ul> 073 * <li><b>Name:</b> <js>"WriterSerializer.quoteChar.s"</js> 074 * <li><b>Data type:</b> <code>String</code> 075 * <li><b>Default:</b> <js>"\""</js> 076 * <li><b>Session property:</b> <jk>false</jk> 077 * <li><b>Methods:</b> 078 * <ul> 079 * <li class='jm'>{@link WriterSerializerBuilder#quoteChar(char)} 080 * <li class='jm'>{@link WriterSerializerBuilder#sq()} 081 * </ul> 082 * </ul> 083 * 084 * <h5 class='section'>Description:</h5> 085 * <p> 086 * This is the character used for quoting attributes and values. 087 * 088 * <p> 089 * This setting does not apply to the RDF serializers. 090 * 091 * <h5 class='section'>Example:</h5> 092 * <p class='bcode w800'> 093 * <jc>// Create a serializer that uses single quotes.</jc> 094 * WriterSerializer s = JsonSerializer 095 * .<jsm>create</jsm>() 096 * .sq() 097 * .build(); 098 * 099 * <jc>// Same, but use property.</jc> 100 * WriterSerializer s = JsonSerializer 101 * .<jsm>create</jsm>() 102 * .set(<jsf>WSERIALIZER_quoteChar</jsf>, <js>'\''</js>) 103 * .build(); 104 * </p> 105 */ 106 public static final String WSERIALIZER_quoteChar = PREFIX + "quoteChar.s"; 107 108 static final WriterSerializer DEFAULT = new WriterSerializer(PropertyStore.create().build(), "", "") { 109 @Override 110 public WriterSerializerSession createSession(SerializerSessionArgs args) { 111 throw new NoSuchMethodError(); 112 } 113 }; 114 115 //------------------------------------------------------------------------------------------------------------------- 116 // Instance 117 //------------------------------------------------------------------------------------------------------------------- 118 119 private final int maxIndent; 120 private final char quoteChar; 121 122 /** 123 * Constructor. 124 * 125 * @param ps 126 * The property store containing all the settings for this object. 127 * @param produces 128 * The media type that this serializer produces. 129 * @param accept 130 * The accept media types that the serializer can handle. 131 * <p> 132 * Can contain meta-characters per the <code>media-type</code> specification of {@doc RFC2616.section14.1} 133 * <p> 134 * If empty, then assumes the only media type supported is <code>produces</code>. 135 * <p> 136 * For example, if this serializer produces <js>"application/json"</js> but should handle media types of 137 * <js>"application/json"</js> and <js>"text/json"</js>, then the arguments should be: 138 * <p class='bcode w800'> 139 * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json,text/json"</js>); 140 * </p> 141 * <br>...or... 142 * <p class='bcode w800'> 143 * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"*​/json"</js>); 144 * </p> 145 * <p> 146 * The accept value can also contain q-values. 147 */ 148 protected WriterSerializer(PropertyStore ps, String produces, String accept) { 149 super(ps, produces, accept); 150 151 maxIndent = getIntegerProperty(WSERIALIZER_maxIndent, 100); 152 quoteChar = getStringProperty(WSERIALIZER_quoteChar, "\"").charAt(0); 153 } 154 155 156 //----------------------------------------------------------------------------------------------------------------- 157 // Abstract methods 158 //----------------------------------------------------------------------------------------------------------------- 159 160 @Override /* SerializerSession */ 161 public abstract WriterSerializerSession createSession(SerializerSessionArgs args); 162 163 164 //----------------------------------------------------------------------------------------------------------------- 165 // Other methods 166 //----------------------------------------------------------------------------------------------------------------- 167 168 @Override /* Serializer */ 169 public final boolean isWriterSerializer() { 170 return true; 171 } 172 173 /** 174 * Convenience method for serializing an object to a <code>String</code>. 175 * 176 * @param o The object to serialize. 177 * @return The output serialized to a string. 178 * @throws SerializeException If a problem occurred trying to convert the output. 179 */ 180 @Override /* Serializer */ 181 public final String serialize(Object o) throws SerializeException { 182 return createSession(createDefaultSessionArgs()).serialize(o); 183 } 184 185 /** 186 * Identical to {@link #serialize(Object)} except throws a {@link RuntimeException} instead of a {@link SerializeException}. 187 * 188 * <p> 189 * This is typically good enough for debugging purposes. 190 * 191 * @param o The object to serialize. 192 * @return The serialized object. 193 */ 194 public final String toString(Object o) { 195 try { 196 return serialize(o); 197 } catch (Exception e) { 198 throw new RuntimeException(e); 199 } 200 } 201 202 /** 203 * Wraps the specified object inside a {@link StringObject}. 204 * 205 * @param o The object to wrap. 206 * @return The wrapped object. 207 */ 208 public final StringObject toStringObject(Object o) { 209 return new StringObject(this, o); 210 } 211 212 /** 213 * Convenience method for serializing an object and sending it to STDOUT. 214 * 215 * @param o The object to serialize. 216 * @return This object (for method chaining). 217 */ 218 public final WriterSerializer println(Object o) { 219 System.out.println(toString(o)); // NOT DEBUG 220 return this; 221 } 222 223 //----------------------------------------------------------------------------------------------------------------- 224 // Properties 225 //----------------------------------------------------------------------------------------------------------------- 226 227 /** 228 * Configuration property: Maximum indentation. 229 * 230 * @see #WSERIALIZER_maxIndent 231 * @return 232 * The maximum indentation level in the serialized document. 233 */ 234 protected final int getMaxIndent() { 235 return maxIndent; 236 } 237 238 /** 239 * Configuration property: Quote character. 240 * 241 * @see #WSERIALIZER_quoteChar 242 * @return 243 * The character used for quoting attributes and values. 244 */ 245 protected final char getQuoteChar() { 246 return quoteChar; 247 } 248 249 @Override /* Context */ 250 public ObjectMap asMap() { 251 return super.asMap() 252 .append("WriterSerializer", new ObjectMap() 253 .append("maxIndent", maxIndent) 254 .append("quoteChar", quoteChar) 255 ); 256 } 257}