BCodec.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */

  17. package org.apache.commons.codec.net;

  18. import java.io.UnsupportedEncodingException;
  19. import java.nio.charset.Charset;

  20. import org.apache.commons.codec.Charsets;
  21. import org.apache.commons.codec.DecoderException;
  22. import org.apache.commons.codec.EncoderException;
  23. import org.apache.commons.codec.StringDecoder;
  24. import org.apache.commons.codec.StringEncoder;
  25. import org.apache.commons.codec.binary.Base64;

  26. /**
  27.  * Identical to the Base64 encoding defined by <a href="http://www.ietf.org/rfc/rfc1521.txt">RFC 1521</a>
  28.  * and allows a character set to be specified.
  29.  * <p>
  30.  * <a href="http://www.ietf.org/rfc/rfc1522.txt">RFC 1522</a> describes techniques to allow the encoding of non-ASCII
  31.  * text in various portions of a RFC 822 [2] message header, in a manner which is unlikely to confuse existing message
  32.  * handling software.
  33.  * <p>
  34.  * This class is immutable and thread-safe.
  35.  *
  36.  * @see <a href="http://www.ietf.org/rfc/rfc1522.txt">MIME (Multipurpose Internet Mail Extensions) Part Two: Message
  37.  *          Header Extensions for Non-ASCII Text</a>
  38.  *
  39.  * @since 1.3
  40.  * @version $Id: BCodec.java 1429868 2013-01-07 16:08:05Z ggregory $
  41.  */
  42. public class BCodec extends RFC1522Codec implements StringEncoder, StringDecoder {
  43.     /**
  44.      * The default charset used for string decoding and encoding.
  45.      */
  46.     private final Charset charset;

  47.     /**
  48.      * Default constructor.
  49.      */
  50.     public BCodec() {
  51.         this(Charsets.UTF_8);
  52.     }

  53.     /**
  54.      * Constructor which allows for the selection of a default charset
  55.      *
  56.      * @param charset
  57.      *            the default string charset to use.
  58.      *
  59.      * @see <a href="http://download.oracle.com/javase/6/docs/api/java/nio/charset/Charset.html">Standard charsets</a>
  60.      * @since 1.7
  61.      */
  62.     public BCodec(final Charset charset) {
  63.         this.charset = charset;
  64.     }

  65.     /**
  66.      * Constructor which allows for the selection of a default charset
  67.      *
  68.      * @param charsetName
  69.      *            the default charset to use.
  70.      * @throws java.nio.charset.UnsupportedCharsetException
  71.      *             If the named charset is unavailable
  72.      * @since 1.7 throws UnsupportedCharsetException if the named charset is unavailable
  73.      * @see <a href="http://download.oracle.com/javase/6/docs/api/java/nio/charset/Charset.html">Standard charsets</a>
  74.      */
  75.     public BCodec(final String charsetName) {
  76.         this(Charset.forName(charsetName));
  77.     }

  78.     @Override
  79.     protected String getEncoding() {
  80.         return "B";
  81.     }

  82.     @Override
  83.     protected byte[] doEncoding(final byte[] bytes) {
  84.         if (bytes == null) {
  85.             return null;
  86.         }
  87.         return Base64.encodeBase64(bytes);
  88.     }

  89.     @Override
  90.     protected byte[] doDecoding(final byte[] bytes) {
  91.         if (bytes == null) {
  92.             return null;
  93.         }
  94.         return Base64.decodeBase64(bytes);
  95.     }

  96.     /**
  97.      * Encodes a string into its Base64 form using the specified charset. Unsafe characters are escaped.
  98.      *
  99.      * @param value
  100.      *            string to convert to Base64 form
  101.      * @param charset
  102.      *            the charset for <code>value</code>
  103.      * @return Base64 string
  104.      * @throws EncoderException
  105.      *             thrown if a failure condition is encountered during the encoding process.
  106.      * @since 1.7
  107.      */
  108.     public String encode(final String value, final Charset charset) throws EncoderException {
  109.         if (value == null) {
  110.             return null;
  111.         }
  112.         return encodeText(value, charset);
  113.     }

  114.     /**
  115.      * Encodes a string into its Base64 form using the specified charset. Unsafe characters are escaped.
  116.      *
  117.      * @param value
  118.      *            string to convert to Base64 form
  119.      * @param charset
  120.      *            the charset for <code>value</code>
  121.      * @return Base64 string
  122.      * @throws EncoderException
  123.      *             thrown if a failure condition is encountered during the encoding process.
  124.      */
  125.     public String encode(final String value, final String charset) throws EncoderException {
  126.         if (value == null) {
  127.             return null;
  128.         }
  129.         try {
  130.             return this.encodeText(value, charset);
  131.         } catch (final UnsupportedEncodingException e) {
  132.             throw new EncoderException(e.getMessage(), e);
  133.         }
  134.     }

  135.     /**
  136.      * Encodes a string into its Base64 form using the default charset. Unsafe characters are escaped.
  137.      *
  138.      * @param value
  139.      *            string to convert to Base64 form
  140.      * @return Base64 string
  141.      * @throws EncoderException
  142.      *             thrown if a failure condition is encountered during the encoding process.
  143.      */
  144.     @Override
  145.     public String encode(final String value) throws EncoderException {
  146.         if (value == null) {
  147.             return null;
  148.         }
  149.         return encode(value, this.getCharset());
  150.     }

  151.     /**
  152.      * Decodes a Base64 string into its original form. Escaped characters are converted back to their original
  153.      * representation.
  154.      *
  155.      * @param value
  156.      *            Base64 string to convert into its original form
  157.      * @return original string
  158.      * @throws DecoderException
  159.      *             A decoder exception is thrown if a failure condition is encountered during the decode process.
  160.      */
  161.     @Override
  162.     public String decode(final String value) throws DecoderException {
  163.         if (value == null) {
  164.             return null;
  165.         }
  166.         try {
  167.             return this.decodeText(value);
  168.         } catch (final UnsupportedEncodingException e) {
  169.             throw new DecoderException(e.getMessage(), e);
  170.         }
  171.     }

  172.     /**
  173.      * Encodes an object into its Base64 form using the default charset. Unsafe characters are escaped.
  174.      *
  175.      * @param value
  176.      *            object to convert to Base64 form
  177.      * @return Base64 object
  178.      * @throws EncoderException
  179.      *             thrown if a failure condition is encountered during the encoding process.
  180.      */
  181.     @Override
  182.     public Object encode(final Object value) throws EncoderException {
  183.         if (value == null) {
  184.             return null;
  185.         } else if (value instanceof String) {
  186.             return encode((String) value);
  187.         } else {
  188.             throw new EncoderException("Objects of type " +
  189.                   value.getClass().getName() +
  190.                   " cannot be encoded using BCodec");
  191.         }
  192.     }

  193.     /**
  194.      * Decodes a Base64 object into its original form. Escaped characters are converted back to their original
  195.      * representation.
  196.      *
  197.      * @param value
  198.      *            Base64 object to convert into its original form
  199.      * @return original object
  200.      * @throws DecoderException
  201.      *             Thrown if the argument is not a <code>String</code>. Thrown if a failure condition is encountered
  202.      *             during the decode process.
  203.      */
  204.     @Override
  205.     public Object decode(final Object value) throws DecoderException {
  206.         if (value == null) {
  207.             return null;
  208.         } else if (value instanceof String) {
  209.             return decode((String) value);
  210.         } else {
  211.             throw new DecoderException("Objects of type " +
  212.                   value.getClass().getName() +
  213.                   " cannot be decoded using BCodec");
  214.         }
  215.     }

  216.     /**
  217.      * Gets the default charset name used for string decoding and encoding.
  218.      *
  219.      * @return the default charset name
  220.      * @since 1.7
  221.      */
  222.     public Charset getCharset() {
  223.         return this.charset;
  224.     }

  225.     /**
  226.      * Gets the default charset name used for string decoding and encoding.
  227.      *
  228.      * @return the default charset name
  229.      */
  230.     public String getDefaultCharset() {
  231.         return this.charset.name();
  232.     }
  233. }