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 */
017
018 package org.apache.commons.codec.net;
019
020 import java.io.UnsupportedEncodingException;
021
022 import org.apache.commons.codec.DecoderException;
023 import org.apache.commons.codec.EncoderException;
024 import org.apache.commons.codec.CharEncoding;
025 import org.apache.commons.codec.StringDecoder;
026 import org.apache.commons.codec.StringEncoder;
027 import org.apache.commons.codec.binary.Base64;
028
029 /**
030 * <p>
031 * Identical to the Base64 encoding defined by <a href="http://www.ietf.org/rfc/rfc1521.txt">RFC
032 * 1521</a> and allows a character set to be specified.
033 * </p>
034 *
035 * <p>
036 * <a href="http://www.ietf.org/rfc/rfc1522.txt">RFC 1522</a> describes techniques to allow the encoding of non-ASCII
037 * text in various portions of a RFC 822 [2] message header, in a manner which is unlikely to confuse existing message
038 * handling software.
039 * </p>
040 *
041 * @see <a href="http://www.ietf.org/rfc/rfc1522.txt">MIME (Multipurpose Internet Mail Extensions) Part Two: Message
042 * Header Extensions for Non-ASCII Text</a>
043 *
044 * @author Apache Software Foundation
045 * @since 1.3
046 * @version $Id: BCodec.java 797857 2009-07-25 23:43:33Z ggregory $
047 */
048 public class BCodec extends RFC1522Codec implements StringEncoder, StringDecoder {
049 /**
050 * The default charset used for string decoding and encoding.
051 */
052 private final String charset;
053
054 /**
055 * Default constructor.
056 */
057 public BCodec() {
058 this(CharEncoding.UTF_8);
059 }
060
061 /**
062 * Constructor which allows for the selection of a default charset
063 *
064 * @param charset
065 * the default string charset to use.
066 *
067 * @see <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/charset/Charset.html">Standard charsets</a>
068 */
069 public BCodec(final String charset) {
070 super();
071 this.charset = charset;
072 }
073
074 protected String getEncoding() {
075 return "B";
076 }
077
078 protected byte[] doEncoding(byte[] bytes) {
079 if (bytes == null) {
080 return null;
081 }
082 return Base64.encodeBase64(bytes);
083 }
084
085 protected byte[] doDecoding(byte[] bytes) {
086 if (bytes == null) {
087 return null;
088 }
089 return Base64.decodeBase64(bytes);
090 }
091
092 /**
093 * Encodes a string into its Base64 form using the specified charset. Unsafe characters are escaped.
094 *
095 * @param value
096 * string to convert to Base64 form
097 * @param charset
098 * the charset for <code>value</code>
099 * @return Base64 string
100 *
101 * @throws EncoderException
102 * thrown if a failure condition is encountered during the encoding process.
103 */
104 public String encode(final String value, final String charset) throws EncoderException {
105 if (value == null) {
106 return null;
107 }
108 try {
109 return encodeText(value, charset);
110 } catch (UnsupportedEncodingException e) {
111 throw new EncoderException(e.getMessage(), e);
112 }
113 }
114
115 /**
116 * Encodes a string into its Base64 form using the default charset. Unsafe characters are escaped.
117 *
118 * @param value
119 * string to convert to Base64 form
120 * @return Base64 string
121 *
122 * @throws EncoderException
123 * thrown if a failure condition is encountered during the encoding process.
124 */
125 public String encode(String value) throws EncoderException {
126 if (value == null) {
127 return null;
128 }
129 return encode(value, getDefaultCharset());
130 }
131
132 /**
133 * Decodes a Base64 string into its original form. Escaped characters are converted back to their original
134 * representation.
135 *
136 * @param value
137 * Base64 string to convert into its original form
138 * @return original string
139 * @throws DecoderException
140 * A decoder exception is thrown if a failure condition is encountered during the decode process.
141 */
142 public String decode(String value) throws DecoderException {
143 if (value == null) {
144 return null;
145 }
146 try {
147 return decodeText(value);
148 } catch (UnsupportedEncodingException e) {
149 throw new DecoderException(e.getMessage(), e);
150 }
151 }
152
153 /**
154 * Encodes an object into its Base64 form using the default charset. Unsafe characters are escaped.
155 *
156 * @param value
157 * object to convert to Base64 form
158 * @return Base64 object
159 *
160 * @throws EncoderException
161 * thrown if a failure condition is encountered during the encoding process.
162 */
163 public Object encode(Object value) throws EncoderException {
164 if (value == null) {
165 return null;
166 } else if (value instanceof String) {
167 return encode((String) value);
168 } else {
169 throw new EncoderException("Objects of type " +
170 value.getClass().getName() +
171 " cannot be encoded using BCodec");
172 }
173 }
174
175 /**
176 * Decodes a Base64 object into its original form. Escaped characters are converted back to their original
177 * representation.
178 *
179 * @param value
180 * Base64 object to convert into its original form
181 *
182 * @return original object
183 *
184 * @throws DecoderException
185 * Thrown if the argument is not a <code>String</code>. Thrown if a failure condition is
186 * encountered during the decode process.
187 */
188 public Object decode(Object value) throws DecoderException {
189 if (value == null) {
190 return null;
191 } else if (value instanceof String) {
192 return decode((String) value);
193 } else {
194 throw new DecoderException("Objects of type " +
195 value.getClass().getName() +
196 " cannot be decoded using BCodec");
197 }
198 }
199
200 /**
201 * The default charset used for string decoding and encoding.
202 *
203 * @return the default string charset.
204 */
205 public String getDefaultCharset() {
206 return this.charset;
207 }
208 }