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.swaps; 018 019import static org.apache.juneau.common.utils.IOUtils.*; 020import static org.apache.juneau.common.utils.StringUtils.*; 021 022import java.io.*; 023 024import org.apache.juneau.*; 025import org.apache.juneau.swap.*; 026 027/** 028 * Transforms <code>InputStreams</code> to {@link String Strings}. 029 * 030 * <h5 class='section'>See Also:</h5><ul> 031 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/SwapBasics">Swap Basics</a> 032 033 * </ul> 034 */ 035public abstract class InputStreamSwap extends StringSwap<InputStream> { 036 037 /** 038 * Converts {@link InputStream InputStreams} to BASE-64 encoding. 039 */ 040 public static class Base64 extends InputStreamSwap { 041 /** 042 * Converts the specified {@link InputStream} to a {@link String}. 043 */ 044 @Override /* ObjectSwap */ 045 public String swap(BeanSession session, InputStream is) throws Exception { 046 return base64Encode(toBytes(is)); 047 } 048 049 /** 050 * Converts the specified {@link String} to an {@link InputStream}. 051 */ 052 @Override /* ObjectSwap */ 053 public InputStream unswap(BeanSession session, String s, ClassMeta<?> hint) throws Exception { 054 return toStream(base64Decode(s), hint); 055 } 056 } 057 058 /** 059 * Converts {@link InputStream InputStreams} to hex encoding. 060 */ 061 public static class Hex extends InputStreamSwap { 062 /** 063 * Converts the specified {@link InputStream} to a {@link String}. 064 */ 065 @Override /* ObjectSwap */ 066 public String swap(BeanSession session, InputStream is) throws Exception { 067 return toHex(toBytes(is)); 068 } 069 070 /** 071 * Converts the specified {@link String} to an {@link InputStream}. 072 */ 073 @Override /* ObjectSwap */ 074 public InputStream unswap(BeanSession session, String s, ClassMeta<?> hint) throws Exception { 075 return toStream(fromHex(s), hint); 076 } 077 } 078 079 /** 080 * Converts {@link InputStream InputStreams} to spaced-hex encoding. 081 */ 082 public static class SpacedHex extends InputStreamSwap { 083 /** 084 * Converts the specified {@link InputStream} to a {@link String}. 085 */ 086 @Override /* ObjectSwap */ 087 public String swap(BeanSession session, InputStream is) throws Exception { 088 return toSpacedHex(toBytes(is)); 089 } 090 091 /** 092 * Converts the specified {@link String} to an {@link InputStream}. 093 */ 094 @Override /* ObjectSwap */ 095 public InputStream unswap(BeanSession session, String s, ClassMeta<?> hint) throws Exception { 096 return toStream(fromSpacedHex(s), hint); 097 } 098 } 099 100 /** 101 * Convert the specified input stream to a byte array. 102 * 103 * @param is 104 * The input stream to convert to bytes. 105 * <br>Can be <jk>null</jk>. 106 * <br>The stream is automatically closed. 107 * @return The byte array. 108 * @throws IOException Thrown by input stream. 109 */ 110 protected byte[] toBytes(InputStream is) throws IOException { 111 return readBytes(is); 112 } 113 114 115 /** 116 * Convert the specified byte array into an input stream. 117 * 118 * @param b The byte array. 119 * @param hint Contains a hint about what subtype is being requested. 120 * @return The byte array. 121 */ 122 protected InputStream toStream(byte[] b, ClassMeta<?> hint) { 123 Class<?> c = hint == null ? InputStream.class : hint.getInnerClass(); 124 if (c == InputStream.class || c == ByteArrayInputStream.class) 125 return new ByteArrayInputStream(b); 126 return null; 127 } 128}