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