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.http.entity; 018 019import static org.apache.juneau.common.utils.IOUtils.*; 020 021import java.io.*; 022import java.nio.charset.*; 023import java.util.function.*; 024 025import org.apache.juneau.common.utils.*; 026import org.apache.juneau.http.header.*; 027import org.apache.juneau.internal.*; 028 029/** 030 * A self contained, repeatable entity that obtains its content from a {@link String}. 031 * 032 * <h5 class='section'>See Also:</h5><ul> 033 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauRestCommonBasics">juneau-rest-common Basics</a> 034 * </ul> 035 */ 036public class StringEntity extends BasicHttpEntity { 037 038 //----------------------------------------------------------------------------------------------------------------- 039 // Static 040 //----------------------------------------------------------------------------------------------------------------- 041 042 private static final String EMPTY = ""; 043 044 //----------------------------------------------------------------------------------------------------------------- 045 // Instance 046 //----------------------------------------------------------------------------------------------------------------- 047 048 private byte[] byteCache; 049 050 /** 051 * Constructor. 052 */ 053 public StringEntity() { 054 } 055 056 /** 057 * Constructor. 058 * 059 * @param contentType The entity content type. 060 * @param content The entity contents. 061 */ 062 public StringEntity(ContentType contentType, String content) { 063 super(contentType, content); 064 } 065 066 /** 067 * Copy constructor. 068 * 069 * @param copyFrom The bean being copied. 070 */ 071 protected StringEntity(StringEntity copyFrom) { 072 super(copyFrom); 073 } 074 075 @Override 076 public StringEntity copy() { 077 return new StringEntity(this); 078 } 079 080 //----------------------------------------------------------------------------------------------------------------- 081 // Other methods 082 //----------------------------------------------------------------------------------------------------------------- 083 084 private String content() { 085 return contentOrElse(EMPTY); 086 } 087 088 @Override /* AbstractHttpEntity */ 089 public String asString() throws IOException { 090 return content(); 091 } 092 093 @Override /* AbstractHttpEntity */ 094 public byte[] asBytes() throws IOException { 095 if (isCached() && byteCache == null) 096 byteCache = content().getBytes(getCharset()); 097 if (byteCache != null) 098 return byteCache; 099 return content().getBytes(getCharset()); 100 } 101 102 @Override /* HttpEntity */ 103 public boolean isRepeatable() { 104 return true; 105 } 106 107 @Override /* HttpEntity */ 108 public long getContentLength() { 109 if (isCached()) 110 return asSafeBytes().length; 111 long l = super.getContentLength(); 112 if (l != -1 || isSupplied()) 113 return l; 114 String s = content(); 115 if (getCharset() == UTF8) 116 for (int i = 0; i < s.length(); i++) 117 if (s.charAt(i) > 127) 118 return -1; 119 return s.length(); 120 } 121 122 @Override /* HttpEntity */ 123 public InputStream getContent() throws IOException { 124 if (isCached()) 125 return new ByteArrayInputStream(asBytes()); 126 return new ReaderInputStream(new StringReader(content()), getCharset()); 127 } 128 129 @Override /* HttpEntity */ 130 public void writeTo(OutputStream out) throws IOException { 131 Utils.assertArgNotNull("out", out); 132 if (isCached()) { 133 out.write(asBytes()); 134 } else { 135 OutputStreamWriter osw = new OutputStreamWriter(out, getCharset()); 136 osw.write(content()); 137 osw.flush(); 138 } 139 } 140 141 @Override /* HttpEntity */ 142 public boolean isStreaming() { 143 return false; 144 } 145 @Override /* Overridden from BasicHttpEntity */ 146 public StringEntity setCached() throws IOException{ 147 super.setCached(); 148 return this; 149 } 150 151 @Override /* Overridden from BasicHttpEntity */ 152 public StringEntity setCharset(Charset value) { 153 super.setCharset(value); 154 return this; 155 } 156 157 @Override /* Overridden from BasicHttpEntity */ 158 public StringEntity setChunked() { 159 super.setChunked(); 160 return this; 161 } 162 163 @Override /* Overridden from BasicHttpEntity */ 164 public StringEntity setChunked(boolean value) { 165 super.setChunked(value); 166 return this; 167 } 168 169 @Override /* Overridden from BasicHttpEntity */ 170 public StringEntity setContent(Object value) { 171 super.setContent(value); 172 return this; 173 } 174 175 @Override /* Overridden from BasicHttpEntity */ 176 public StringEntity setContent(Supplier<?> value) { 177 super.setContent(value); 178 return this; 179 } 180 181 @Override /* Overridden from BasicHttpEntity */ 182 public StringEntity setContentEncoding(String value) { 183 super.setContentEncoding(value); 184 return this; 185 } 186 187 @Override /* Overridden from BasicHttpEntity */ 188 public StringEntity setContentEncoding(ContentEncoding value) { 189 super.setContentEncoding(value); 190 return this; 191 } 192 193 @Override /* Overridden from BasicHttpEntity */ 194 public StringEntity setContentLength(long value) { 195 super.setContentLength(value); 196 return this; 197 } 198 199 @Override /* Overridden from BasicHttpEntity */ 200 public StringEntity setContentType(String value) { 201 super.setContentType(value); 202 return this; 203 } 204 205 @Override /* Overridden from BasicHttpEntity */ 206 public StringEntity setContentType(ContentType value) { 207 super.setContentType(value); 208 return this; 209 } 210 211 @Override /* Overridden from BasicHttpEntity */ 212 public StringEntity setMaxLength(int value) { 213 super.setMaxLength(value); 214 return this; 215 } 216 217 @Override /* Overridden from BasicHttpEntity */ 218 public StringEntity setUnmodifiable() { 219 super.setUnmodifiable(); 220 return this; 221 } 222}