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