1 package com.fasterxml.jackson.core; 2 3 import java.io.*; 4 import java.net.URL; 5 6 import com.fasterxml.jackson.core.io.DataOutputAsStream; 7 8 /** 9 * Intermediate base class for actual format-specific factories for constructing 10 * parsers (reading) and generators (writing). Although full power will only be 11 * available with Jackson 3, skeletal implementation added in 2.10 to help conversion 12 * of code for 2.x to 3.x migration of projects depending on Jackson 13 * 14 * @since 2.10 15 */ 16 public abstract class TokenStreamFactory 17 implements Versioned, 18 java.io.Serializable 19 { 20 private static final long serialVersionUID = 2; 21 22 /* 23 /********************************************************** 24 /* Capability introspection 25 /********************************************************** 26 */ 27 28 /** 29 * Introspection method that higher-level functionality may call 30 * to see whether underlying data format requires a stable ordering 31 * of object properties or not. 32 * This is usually used for determining 33 * whether to force a stable ordering (like alphabetic ordering by name) 34 * if no ordering if explicitly specified. 35 *<p> 36 * Default implementation returns <code>false</code> as JSON does NOT 37 * require stable ordering. Formats that require ordering include positional 38 * textual formats like <code>CSV</code>, and schema-based binary formats 39 * like <code>Avro</code>. 40 */ requiresPropertyOrdering()41 public abstract boolean requiresPropertyOrdering(); 42 43 /** 44 * Introspection method that higher-level functionality may call 45 * to see whether underlying data format can read and write binary 46 * data natively; that is, embeded it as-is without using encodings 47 * such as Base64. 48 *<p> 49 * Default implementation returns <code>false</code> as JSON does not 50 * support native access: all binary content must use Base64 encoding. 51 * Most binary formats (like Smile and Avro) support native binary content. 52 */ canHandleBinaryNatively()53 public abstract boolean canHandleBinaryNatively(); 54 55 /** 56 * Introspection method that can be used to check whether this 57 * factory can create non-blocking parsers: parsers that do not 58 * use blocking I/O abstractions but instead use a 59 * {@link com.fasterxml.jackson.core.async.NonBlockingInputFeeder}. 60 */ canParseAsync()61 public abstract boolean canParseAsync(); 62 63 /** 64 * Method for accessing kind of {@link FormatFeature} that a parser 65 * {@link JsonParser} produced by this factory would accept, if any; 66 * <code>null</code> returned if none. 67 * 68 * @since 2.6 69 */ getFormatReadFeatureType()70 public abstract Class<? extends FormatFeature> getFormatReadFeatureType(); 71 72 /** 73 * Method for accessing kind of {@link FormatFeature} that a parser 74 * {@link JsonGenerator} produced by this factory would accept, if any; 75 * <code>null</code> returned if none. 76 * 77 * @since 2.6 78 */ getFormatWriteFeatureType()79 public abstract Class<? extends FormatFeature> getFormatWriteFeatureType(); 80 81 /* 82 /********************************************************** 83 /* Format detection functionality 84 /********************************************************** 85 */ 86 87 /** 88 * Method that can be used to quickly check whether given schema 89 * is something that parsers and/or generators constructed by this 90 * factory could use. Note that this means possible use, at the level 91 * of data format (i.e. schema is for same data format as parsers and 92 * generators this factory constructs); individual schema instances 93 * may have further usage restrictions. 94 * 95 * @since 2.1 96 */ canUseSchema(FormatSchema schema)97 public abstract boolean canUseSchema(FormatSchema schema); 98 99 /** 100 * Method that returns short textual id identifying format 101 * this factory supports. 102 */ getFormatName()103 public abstract String getFormatName(); 104 105 /* 106 /********************************************************** 107 /* Configuration access 108 /********************************************************** 109 */ 110 isEnabled(JsonParser.Feature f)111 public abstract boolean isEnabled(JsonParser.Feature f); isEnabled(JsonGenerator.Feature f)112 public abstract boolean isEnabled(JsonGenerator.Feature f); 113 getParserFeatures()114 public abstract int getParserFeatures(); getGeneratorFeatures()115 public abstract int getGeneratorFeatures(); 116 getFormatParserFeatures()117 public abstract int getFormatParserFeatures(); getFormatGeneratorFeatures()118 public abstract int getFormatGeneratorFeatures(); 119 120 /* 121 /********************************************************** 122 /* Factory methods, parsers 123 /********************************************************** 124 */ 125 createParser(byte[] data)126 public abstract JsonParser createParser(byte[] data) throws IOException; createParser(byte[] data, int offset, int len)127 public abstract JsonParser createParser(byte[] data, int offset, int len) throws IOException; createParser(char[] content)128 public abstract JsonParser createParser(char[] content) throws IOException; createParser(char[] content, int offset, int len)129 public abstract JsonParser createParser(char[] content, int offset, int len) throws IOException; createParser(DataInput in)130 public abstract JsonParser createParser(DataInput in) throws IOException; createParser(File f)131 public abstract JsonParser createParser(File f) throws IOException; createParser(InputStream in)132 public abstract JsonParser createParser(InputStream in) throws IOException; createParser(Reader r)133 public abstract JsonParser createParser(Reader r) throws IOException; createParser(String content)134 public abstract JsonParser createParser(String content) throws IOException; createParser(URL url)135 public abstract JsonParser createParser(URL url) throws IOException; 136 createNonBlockingByteArrayParser()137 public abstract JsonParser createNonBlockingByteArrayParser() throws IOException; 138 139 /* 140 /********************************************************** 141 /* Factory methods, generators 142 /********************************************************** 143 */ 144 createGenerator(DataOutput out, JsonEncoding enc)145 public abstract JsonGenerator createGenerator(DataOutput out, JsonEncoding enc) throws IOException; createGenerator(DataOutput out)146 public abstract JsonGenerator createGenerator(DataOutput out) throws IOException; createGenerator(File f, JsonEncoding enc)147 public abstract JsonGenerator createGenerator(File f, JsonEncoding enc) throws IOException; createGenerator(OutputStream out)148 public abstract JsonGenerator createGenerator(OutputStream out) throws IOException; createGenerator(OutputStream out, JsonEncoding enc)149 public abstract JsonGenerator createGenerator(OutputStream out, JsonEncoding enc) throws IOException; createGenerator(Writer w)150 public abstract JsonGenerator createGenerator(Writer w) throws IOException; 151 152 /* 153 /********************************************************** 154 /* Internal factory methods, other 155 /********************************************************** 156 */ 157 _createDataOutputWrapper(DataOutput out)158 protected OutputStream _createDataOutputWrapper(DataOutput out) { 159 return new DataOutputAsStream(out); 160 } 161 /** 162 * Helper methods used for constructing an optimal stream for 163 * parsers to use, when input is to be read from an URL. 164 * This helps when reading file content via URL. 165 */ _optimizedStreamFromURL(URL url)166 protected InputStream _optimizedStreamFromURL(URL url) throws IOException { 167 if ("file".equals(url.getProtocol())) { 168 /* Can not do this if the path refers 169 * to a network drive on windows. This fixes the problem; 170 * might not be needed on all platforms (NFS?), but should not 171 * matter a lot: performance penalty of extra wrapping is more 172 * relevant when accessing local file system. 173 */ 174 String host = url.getHost(); 175 if (host == null || host.length() == 0) { 176 // [core#48]: Let's try to avoid probs with URL encoded stuff 177 String path = url.getPath(); 178 if (path.indexOf('%') < 0) { 179 return new FileInputStream(url.getPath()); 180 181 } 182 // otherwise, let's fall through and let URL decoder do its magic 183 } 184 } 185 return url.openStream(); 186 } 187 } 188