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.parser; 018 019import static org.apache.juneau.commons.utils.AssertionUtils.*; 020 021import java.io.*; 022import java.lang.reflect.*; 023import java.nio.charset.*; 024import java.util.*; 025import java.util.function.*; 026 027import org.apache.juneau.*; 028import org.apache.juneau.commons.collections.FluentMap; 029import org.apache.juneau.httppart.*; 030 031/** 032 * Subclass of parser session objects for character-based parsers. 033 * 034 * <h5 class='section'>Notes:</h5><ul> 035 * <li class='warn'>This class is not thread safe and is typically discarded after one use. 036 * </ul> 037 * 038 * <h5 class='section'>See Also:</h5><ul> 039 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/SerializersAndParsers">Serializers and Parsers</a> 040 * </ul> 041 */ 042public class ReaderParserSession extends ParserSession { 043 /** 044 * Builder class. 045 */ 046 public static class Builder extends ParserSession.Builder { 047 048 private Charset fileCharset; 049 private Charset streamCharset; 050 private ReaderParser ctx; 051 052 /** 053 * Constructor 054 * 055 * @param ctx The context creating this session. 056 * <br>Cannot be <jk>null</jk>. 057 */ 058 protected Builder(ReaderParser ctx) { 059 super(assertArgNotNull("ctx", ctx)); 060 this.ctx = ctx; 061 fileCharset = ctx.getFileCharset(); 062 streamCharset = ctx.getStreamCharset(); 063 } 064 065 @Override /* Overridden from Builder */ 066 public <T> Builder apply(Class<T> type, Consumer<T> apply) { 067 super.apply(type, apply); 068 return this; 069 } 070 071 @Override 072 public ReaderParserSession build() { 073 return new ReaderParserSession(this); 074 } 075 076 @Override /* Overridden from Builder */ 077 public Builder debug(Boolean value) { 078 super.debug(value); 079 return this; 080 } 081 082 /** 083 * File charset. 084 * 085 * <p> 086 * The character set to use for reading Files from the file system. 087 * 088 * <p> 089 * Used when passing in files to {@link Parser#parse(Object, Class)}. 090 * 091 * <p> 092 * If not specified, defaults to the JVM system default charset. 093 * 094 * @param value 095 * The new property value. 096 * <br>Can be <jk>null</jk>. 097 * @return This object. 098 */ 099 public Builder fileCharset(Charset value) { 100 fileCharset = value; 101 return this; 102 } 103 104 @Override /* Overridden from Builder */ 105 public Builder javaMethod(Method value) { 106 super.javaMethod(value); 107 return this; 108 } 109 110 @Override /* Overridden from Builder */ 111 public Builder locale(Locale value) { 112 super.locale(value); 113 return this; 114 } 115 116 @Override /* Overridden from Builder */ 117 public Builder mediaType(MediaType value) { 118 super.mediaType(value); 119 return this; 120 } 121 122 @Override /* Overridden from Builder */ 123 public Builder mediaTypeDefault(MediaType value) { 124 super.mediaTypeDefault(value); 125 return this; 126 } 127 128 @Override /* Overridden from Builder */ 129 public Builder outer(Object value) { 130 super.outer(value); 131 return this; 132 } 133 134 @Override /* Overridden from Builder */ 135 public Builder properties(Map<String,Object> value) { 136 super.properties(value); 137 return this; 138 } 139 140 @Override /* Overridden from Builder */ 141 public Builder property(String key, Object value) { 142 super.property(key, value); 143 return this; 144 } 145 146 @Override /* Overridden from Builder */ 147 public Builder schema(HttpPartSchema value) { 148 super.schema(value); 149 return this; 150 } 151 152 @Override /* Overridden from Builder */ 153 public Builder schemaDefault(HttpPartSchema value) { 154 super.schemaDefault(value); 155 return this; 156 } 157 158 /** 159 * Input stream charset. 160 * 161 * <p> 162 * The character set to use for converting InputStreams and byte arrays to readers. 163 * 164 * <p> 165 * Used when passing in input streams and byte arrays to {@link Parser#parse(Object, Class)}. 166 * 167 * <p> 168 * If not specified, defaults to UTF-8. 169 * 170 * @param value 171 * The new property value. 172 * <br>Can be <jk>null</jk> (defaults to UTF-8). 173 * @return This object. 174 */ 175 public Builder streamCharset(Charset value) { 176 streamCharset = value; 177 return this; 178 } 179 180 @Override /* Overridden from Builder */ 181 public Builder timeZone(TimeZone value) { 182 super.timeZone(value); 183 return this; 184 } 185 186 @Override /* Overridden from Builder */ 187 public Builder timeZoneDefault(TimeZone value) { 188 super.timeZoneDefault(value); 189 return this; 190 } 191 192 @Override /* Overridden from Builder */ 193 public Builder unmodifiable() { 194 super.unmodifiable(); 195 return this; 196 } 197 } 198 199 /** 200 * Creates a new builder for this object. 201 * 202 * @param ctx The context creating this session. 203 * <br>Cannot be <jk>null</jk>. 204 * @return A new builder. 205 */ 206 public static Builder create(ReaderParser ctx) { 207 return new Builder(assertArgNotNull("ctx", ctx)); 208 } 209 210 private final ReaderParser ctx; 211 private final Charset fileCharset; 212 private final Charset streamCharset; 213 214 /** 215 * Constructor. 216 * 217 * @param builder The builder for this object. 218 */ 219 protected ReaderParserSession(Builder builder) { 220 super(builder); 221 ctx = builder.ctx; 222 fileCharset = builder.fileCharset; 223 streamCharset = builder.streamCharset; 224 } 225 226 /** 227 * Wraps the specified input object into a {@link ParserPipe} object so that it can be easily converted into 228 * a stream or reader. 229 * 230 * @param input 231 * The input. 232 * <br>This can be any of the following types: 233 * <ul> 234 * <li><jk>null</jk> 235 * <li>{@link Reader} 236 * <li>{@link CharSequence} 237 * <li>{@link InputStream} containing UTF-8 encoded text (or whatever the encoding specified by 238 * {@link ReaderParser.Builder#streamCharset(Charset)}). 239 * <li><code><jk>byte</jk>[]</code> containing UTF-8 encoded text (or whatever the encoding specified by 240 * {@link ReaderParser.Builder#streamCharset(Charset)}). 241 * <li>{@link File} containing system encoded text (or whatever the encoding specified by 242 * {@link ReaderParser.Builder#streamCharset(Charset)}). 243 * </ul> 244 * @return 245 * A new {@link ParserPipe} wrapper around the specified input object. 246 */ 247 @SuppressWarnings("resource") 248 @Override /* Overridden from ParserSesson */ 249 public final ParserPipe createPipe(Object input) { 250 return setPipe(new ParserPipe(input, isDebug(), ctx.isStrict(), ctx.isAutoCloseStreams(), ctx.isUnbuffered(), streamCharset, fileCharset)); 251 } 252 253 /** 254 * Returns the file charset defined on this session. 255 * 256 * @return the file charset defined on this session. 257 */ 258 public Charset getFileCharset() { return fileCharset; } 259 260 /** 261 * Returns the stream charset defined on this session. 262 * 263 * @return the stream charset defined on this session. 264 */ 265 public Charset getStreamCharset() { return streamCharset; } 266 267 @Override /* Overridden from ParserSession */ 268 public final boolean isReaderParser() { return true; } 269 270 @Override /* Overridden from ParserSession */ 271 protected FluentMap<String,Object> properties() { 272 return super.properties() 273 .a("fileCharset", fileCharset) 274 .a("streamCharset", streamCharset); 275 } 276}