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