1 package com.fasterxml.jackson.core; 2 3 import com.fasterxml.jackson.core.io.InputDecorator; 4 import com.fasterxml.jackson.core.io.OutputDecorator; 5 import com.fasterxml.jackson.core.json.JsonReadFeature; 6 import com.fasterxml.jackson.core.json.JsonWriteFeature; 7 8 /** 9 * Since 2.10, Builder class is offered for creating token stream factories 10 * with difference configurations: with 3.x they will be fully immutable. 11 * 12 * @since 2.10 13 */ 14 public abstract class TSFBuilder<F extends JsonFactory, 15 B extends TSFBuilder<F,B>> 16 { 17 /* 18 /********************************************************************** 19 /* Constants 20 /********************************************************************** 21 */ 22 23 /** 24 * Bitfield (set of flags) of all factory features that are enabled by default. 25 */ 26 protected final static int DEFAULT_FACTORY_FEATURE_FLAGS = JsonFactory.Feature.collectDefaults(); 27 28 /** 29 * Bitfield (set of flags) of all parser features that are enabled 30 * by default. 31 */ 32 protected final static int DEFAULT_PARSER_FEATURE_FLAGS = JsonParser.Feature.collectDefaults(); 33 34 /** 35 * Bitfield (set of flags) of all generator features that are enabled 36 * by default. 37 */ 38 protected final static int DEFAULT_GENERATOR_FEATURE_FLAGS = JsonGenerator.Feature.collectDefaults(); 39 40 /* 41 /********************************************************************** 42 /* Configured features 43 /********************************************************************** 44 */ 45 46 /** 47 * Set of {@link com.fasterxml.jackson.core.JsonFactory.Feature}s enabled, 48 * as bitmask. 49 */ 50 protected int _factoryFeatures; 51 52 /** 53 * Set of {@link JsonParser.Feature}s enabled, as bitmask. 54 */ 55 protected int _streamReadFeatures; 56 57 /** 58 * Set of {@link JsonGenerator.Feature}s enabled, as bitmask. 59 */ 60 protected int _streamWriteFeatures; 61 62 /* 63 /********************************************************************** 64 /* Other configuration 65 /********************************************************************** 66 */ 67 68 /** 69 * Optional helper object that may decorate input sources, to do 70 * additional processing on input during parsing. 71 */ 72 protected InputDecorator _inputDecorator; 73 74 /** 75 * Optional helper object that may decorate output object, to do 76 * additional processing on output during content generation. 77 */ 78 protected OutputDecorator _outputDecorator; 79 80 /* 81 /********************************************************************** 82 /* Construction 83 /********************************************************************** 84 */ 85 TSFBuilder()86 protected TSFBuilder() { 87 _factoryFeatures = DEFAULT_FACTORY_FEATURE_FLAGS; 88 _streamReadFeatures = DEFAULT_PARSER_FEATURE_FLAGS; 89 _streamWriteFeatures = DEFAULT_GENERATOR_FEATURE_FLAGS; 90 _inputDecorator = null; 91 _outputDecorator = null; 92 } 93 TSFBuilder(JsonFactory base)94 protected TSFBuilder(JsonFactory base) 95 { 96 this(base._factoryFeatures, 97 base._parserFeatures, base._generatorFeatures); 98 } 99 TSFBuilder(int factoryFeatures, int parserFeatures, int generatorFeatures)100 protected TSFBuilder(int factoryFeatures, 101 int parserFeatures, int generatorFeatures) 102 { 103 _factoryFeatures = factoryFeatures; 104 _streamReadFeatures = parserFeatures; 105 _streamWriteFeatures = generatorFeatures; 106 } 107 108 // // // Accessors 109 factoryFeaturesMask()110 public int factoryFeaturesMask() { return _factoryFeatures; } streamReadFeatures()111 public int streamReadFeatures() { return _streamReadFeatures; } streamWriteFeatures()112 public int streamWriteFeatures() { return _streamWriteFeatures; } 113 inputDecorator()114 public InputDecorator inputDecorator() { return _inputDecorator; } outputDecorator()115 public OutputDecorator outputDecorator() { return _outputDecorator; } 116 117 // // // Factory features 118 enable(JsonFactory.Feature f)119 public B enable(JsonFactory.Feature f) { 120 _factoryFeatures |= f.getMask(); 121 return _this(); 122 } 123 disable(JsonFactory.Feature f)124 public B disable(JsonFactory.Feature f) { 125 _factoryFeatures &= ~f.getMask(); 126 return _this(); 127 } 128 configure(JsonFactory.Feature f, boolean state)129 public B configure(JsonFactory.Feature f, boolean state) { 130 return state ? enable(f) : disable(f); 131 } 132 133 // // // StreamReadFeatures (replacement of non-json-specific parser features) 134 enable(StreamReadFeature f)135 public B enable(StreamReadFeature f) { 136 _streamReadFeatures |= f.mappedFeature().getMask(); 137 return _this(); 138 } 139 enable(StreamReadFeature first, StreamReadFeature... other)140 public B enable(StreamReadFeature first, StreamReadFeature... other) { 141 _streamReadFeatures |= first.mappedFeature().getMask(); 142 for (StreamReadFeature f : other) { 143 _streamReadFeatures |= f.mappedFeature().getMask(); 144 } 145 return _this(); 146 } 147 disable(StreamReadFeature f)148 public B disable(StreamReadFeature f) { 149 _streamReadFeatures &= ~f.mappedFeature().getMask(); 150 return _this(); 151 } 152 disable(StreamReadFeature first, StreamReadFeature... other)153 public B disable(StreamReadFeature first, StreamReadFeature... other) { 154 _streamReadFeatures &= ~first.mappedFeature().getMask(); 155 for (StreamReadFeature f : other) { 156 _streamReadFeatures &= ~f.mappedFeature().getMask(); 157 } 158 return _this(); 159 } 160 configure(StreamReadFeature f, boolean state)161 public B configure(StreamReadFeature f, boolean state) { 162 return state ? enable(f) : disable(f); 163 } 164 165 // // // StreamWriteFeatures (replacement of non-json-specific generator features) 166 enable(StreamWriteFeature f)167 public B enable(StreamWriteFeature f) { 168 _streamWriteFeatures |= f.mappedFeature().getMask(); 169 return _this(); 170 } 171 enable(StreamWriteFeature first, StreamWriteFeature... other)172 public B enable(StreamWriteFeature first, StreamWriteFeature... other) { 173 _streamWriteFeatures |= first.mappedFeature().getMask(); 174 for (StreamWriteFeature f : other) { 175 _streamWriteFeatures |= f.mappedFeature().getMask(); 176 } 177 return _this(); 178 } 179 disable(StreamWriteFeature f)180 public B disable(StreamWriteFeature f) { 181 _streamWriteFeatures &= ~f.mappedFeature().getMask(); 182 return _this(); 183 } 184 disable(StreamWriteFeature first, StreamWriteFeature... other)185 public B disable(StreamWriteFeature first, StreamWriteFeature... other) { 186 _streamWriteFeatures &= ~first.mappedFeature().getMask(); 187 for (StreamWriteFeature f : other) { 188 _streamWriteFeatures &= ~f.mappedFeature().getMask(); 189 } 190 return _this(); 191 } 192 configure(StreamWriteFeature f, boolean state)193 public B configure(StreamWriteFeature f, boolean state) { 194 return state ? enable(f) : disable(f); 195 } 196 197 /* 26-Jun-2018, tatu: This should not be needed here, but due to 2.x limitations, 198 * we do need to include it or require casting. 199 * Specifically: since `JsonFactory` (and not `TokenStreamFactory`) is base class 200 * for all backends, it can not expose JSON-specific builder, but this. 201 * So let's select lesser evil(s). 202 */ 203 204 // // // JSON-specific, reads 205 enable(JsonReadFeature f)206 public B enable(JsonReadFeature f) { 207 return _failNonJSON(f); 208 } 209 enable(JsonReadFeature first, JsonReadFeature... other)210 public B enable(JsonReadFeature first, JsonReadFeature... other) { 211 return _failNonJSON(first); 212 } 213 disable(JsonReadFeature f)214 public B disable(JsonReadFeature f) { 215 return _failNonJSON(f); 216 } 217 disable(JsonReadFeature first, JsonReadFeature... other)218 public B disable(JsonReadFeature first, JsonReadFeature... other) { 219 return _failNonJSON(first); 220 } 221 configure(JsonReadFeature f, boolean state)222 public B configure(JsonReadFeature f, boolean state) { 223 return _failNonJSON(f); 224 } 225 _failNonJSON(Object feature)226 private B _failNonJSON(Object feature) { 227 throw new IllegalArgumentException("Feature "+feature.getClass().getName() 228 +"#"+feature.toString()+" not supported for non-JSON backend"); 229 } 230 231 // // // JSON-specific, writes 232 enable(JsonWriteFeature f)233 public B enable(JsonWriteFeature f) { 234 return _failNonJSON(f); 235 } 236 enable(JsonWriteFeature first, JsonWriteFeature... other)237 public B enable(JsonWriteFeature first, JsonWriteFeature... other) { 238 return _failNonJSON(first); 239 } 240 disable(JsonWriteFeature f)241 public B disable(JsonWriteFeature f) { 242 return _failNonJSON(f); 243 } 244 disable(JsonWriteFeature first, JsonWriteFeature... other)245 public B disable(JsonWriteFeature first, JsonWriteFeature... other) { 246 return _failNonJSON(first); 247 } 248 configure(JsonWriteFeature f, boolean state)249 public B configure(JsonWriteFeature f, boolean state) { 250 return _failNonJSON(f); 251 } 252 253 // // // Other configuration 254 inputDecorator(InputDecorator dec)255 public B inputDecorator(InputDecorator dec) { 256 _inputDecorator = dec; 257 return _this(); 258 } 259 outputDecorator(OutputDecorator dec)260 public B outputDecorator(OutputDecorator dec) { 261 _outputDecorator = dec; 262 return _this(); 263 } 264 265 // // // Other methods 266 267 /** 268 * Method for constructing actual {@link TokenStreamFactory} instance, given 269 * configuration. 270 */ build()271 public abstract F build(); 272 273 // silly convenience cast method we need 274 @SuppressWarnings("unchecked") _this()275 protected final B _this() { return (B) this; } 276 277 // // // Support for subtypes 278 _legacyEnable(JsonParser.Feature f)279 protected void _legacyEnable(JsonParser.Feature f) { 280 if (f != null) { 281 _streamReadFeatures |= f.getMask(); 282 } 283 } 284 _legacyDisable(JsonParser.Feature f)285 protected void _legacyDisable(JsonParser.Feature f) { 286 if (f != null) { 287 _streamReadFeatures &= ~f.getMask(); 288 } 289 } 290 _legacyEnable(JsonGenerator.Feature f)291 protected void _legacyEnable(JsonGenerator.Feature f) { 292 if (f != null) { 293 _streamWriteFeatures |= f.getMask(); 294 } 295 } _legacyDisable(JsonGenerator.Feature f)296 protected void _legacyDisable(JsonGenerator.Feature f) { 297 if (f != null) { 298 _streamWriteFeatures &= ~f.getMask(); 299 } 300 } 301 } 302