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