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.parser; 014 015import java.nio.charset.*; 016 017import org.apache.juneau.*; 018import org.apache.juneau.annotation.*; 019import org.apache.juneau.collections.*; 020import org.apache.juneau.internal.*; 021 022/** 023 * Subclass of {@link Parser} for characters-based parsers. 024 * 025 * <h5 class='topic'>Description</h5> 026 * 027 * This class is typically the parent class of all character-based parsers. 028 * It has 1 abstract method to implement... 029 * <ul> 030 * <li><c>parse(ParserSession, ClassMeta)</c> 031 * </ul> 032 */ 033@ConfigurableContext 034public abstract class ReaderParser extends Parser { 035 036 //------------------------------------------------------------------------------------------------------------------- 037 // Configurable properties 038 //------------------------------------------------------------------------------------------------------------------- 039 040 static final String PREFIX = "ReaderParser"; 041 042 /** 043 * Configuration property: File charset. 044 * 045 * <h5 class='section'>Property:</h5> 046 * <ul class='spaced-list'> 047 * <li><b>ID:</b> {@link org.apache.juneau.parser.ReaderParser#RPARSER_fileCharset RPARSER_fileCharset} 048 * <li><b>Name:</b> <js>"ReaderParser.fileCharset.s"</js> 049 * <li><b>Data type:</b> <c>String</c> 050 * <li><b>System property:</b> <c>ReaderParser.fileCharset</c> 051 * <li><b>Environment variable:</b> <c>READERPARSER_FILECHARSET</c> 052 * <li><b>Default:</b> <js>"DEFAULT"</js> 053 * <li><b>Session property:</b> <jk>false</jk> 054 * <li><b>Annotations:</b> 055 * <ul> 056 * <li class='ja'>{@link org.apache.juneau.parser.annotation.ParserConfig#fileCharset()} 057 * </ul> 058 * <li><b>Methods:</b> 059 * <ul> 060 * <li class='jm'>{@link org.apache.juneau.parser.ReaderParserBuilder#fileCharset(Charset)} 061 * </ul> 062 * </ul> 063 * 064 * <h5 class='section'>Description:</h5> 065 * 066 * <p> 067 * The character set to use for reading <c>Files</c> from the file system. 068 * 069 * <p> 070 * Used when passing in files to {@link Parser#parse(Object, Class)}. 071 * 072 * <p> 073 * <js>"DEFAULT"</js> can be used to indicate the JVM default file system charset. 074 * 075 * <h5 class='section'>Example:</h5> 076 * <p class='bcode w800'> 077 * <jc>// Create a parser that reads UTF-8 files.</jc> 078 * ReaderParser p = JsonParser 079 * .<jsm>create</jsm>() 080 * .fileCharset(<js>"UTF-8"</js>) 081 * .build(); 082 * 083 * <jc>// Same, but use property.</jc> 084 * ReaderParser p = JsonParser 085 * .<jsm>create</jsm>() 086 * .set(<jsf>RPARSER_fileCharset</jsf>, <js>"UTF-8"</js>) 087 * .build(); 088 * 089 * <jc>// Use it to read a UTF-8 encoded file.</jc> 090 * MyBean myBean = p.parse(<jk>new</jk> File(<js>"MyBean.txt"</js>), MyBean.<jk>class</jk>); 091 * </p> 092 */ 093 public static final String RPARSER_fileCharset = PREFIX + ".fileCharset.s"; 094 095 /** 096 * Configuration property: Input stream charset. 097 * 098 * <h5 class='section'>Property:</h5> 099 * <ul class='spaced-list'> 100 * <li><b>ID:</b> {@link org.apache.juneau.parser.ReaderParser#RPARSER_streamCharset RPARSER_streamCharset} 101 * <li><b>Name:</b> <js>"ReaderParser.streamCharset.s"</js> 102 * <li><b>Data type:</b> <c>String</c> 103 * <li><b>System property:</b> <c>ReaderParser.streamCharset</c> 104 * <li><b>Environment variable:</b> <c>READERPARSER_STREAMCHARSET</c> 105 * <li><b>Default:</b> <js>"UTF-8"</js> 106 * <li><b>Session property:</b> <jk>false</jk> 107 * <li><b>Annotations:</b> 108 * <ul> 109 * <li class='ja'>{@link org.apache.juneau.parser.annotation.ParserConfig#streamCharset()} 110 * </ul> 111 * <li><b>Methods:</b> 112 * <ul> 113 * <li class='jm'>{@link org.apache.juneau.parser.ReaderParserBuilder#streamCharset(Charset)} 114 * </ul> 115 * </ul> 116 * 117 * <h5 class='section'>Description:</h5> 118 * 119 * <p> 120 * The character set to use for converting <c>InputStreams</c> and byte arrays to readers. 121 * 122 * <p> 123 * Used when passing in input streams and byte arrays to {@link Parser#parse(Object, Class)}. 124 * 125 * <h5 class='section'>Example:</h5> 126 * <p class='bcode w800'> 127 * <jc>// Create a parser that reads UTF-8 files.</jc> 128 * ReaderParser p = JsonParser 129 * .<jsm>create</jsm>() 130 * .streamCharset(Charset.<jsm>forName</jsm>(<js>"UTF-8"</js>)) 131 * .build(); 132 * 133 * <jc>// Same, but use property.</jc> 134 * ReaderParser p = JsonParser 135 * .<jsm>create</jsm>() 136 * .set(<jsf>RPARSER_streamCharset</jsf>, <js>"UTF-8"</js>) 137 * .build(); 138 * 139 * <jc>// Use it to read a UTF-8 encoded input stream.</jc> 140 * MyBean myBean = p.parse(<jk>new</jk> FileInputStream(<js>"MyBean.txt"</js>), MyBean.<jk>class</jk>); 141 * </p> 142 */ 143 public static final String RPARSER_streamCharset = PREFIX + ".streamCharset.s"; 144 145 static final ReaderParser DEFAULT = new ReaderParser(PropertyStore.create().build(), "") { 146 @Override 147 public ReaderParserSession createSession(ParserSessionArgs args) { 148 throw new NoSuchMethodError(); 149 } 150 }; 151 152 //------------------------------------------------------------------------------------------------------------------- 153 // Instance 154 //------------------------------------------------------------------------------------------------------------------- 155 156 private final Charset streamCharset, fileCharset; 157 158 /** 159 * Constructor. 160 * 161 * @param ps The property store containing all the settings for this object. 162 * @param consumes The list of media types that this parser consumes (e.g. <js>"application/json"</js>, <js>"*​/json"</js>). 163 */ 164 protected ReaderParser(PropertyStore ps, String...consumes) { 165 super(ps, consumes); 166 167 streamCharset = getProperty(RPARSER_streamCharset, Charset.class, IOUtils.UTF8); 168 fileCharset = getProperty(RPARSER_fileCharset, Charset.class, Charset.defaultCharset()); 169 } 170 171 @Override /* Parser */ 172 public final boolean isReaderParser() { 173 return true; 174 } 175 176 //----------------------------------------------------------------------------------------------------------------- 177 // Properties 178 //----------------------------------------------------------------------------------------------------------------- 179 180 /** 181 * File charset. 182 * 183 * @see #RPARSER_fileCharset 184 * @return 185 * The character set to use for reading <c>Files</c> from the file system. 186 */ 187 protected final Charset getFileCharset() { 188 return fileCharset; 189 } 190 191 /** 192 * Input stream charset. 193 * 194 * @see #RPARSER_streamCharset 195 * @return 196 * The character set to use for converting <c>InputStreams</c> and byte arrays to readers. 197 */ 198 protected final Charset getStreamCharset() { 199 return streamCharset; 200 } 201 202 //----------------------------------------------------------------------------------------------------------------- 203 // Other methods 204 //----------------------------------------------------------------------------------------------------------------- 205 206 @Override /* Context */ 207 public OMap toMap() { 208 return super.toMap() 209 .a("ReaderParser", new DefaultFilteringOMap() 210 .a("fileCharset", fileCharset) 211 .a("streamCharset", streamCharset) 212 ); 213 } 214}