001/*
002 * ============================================================================
003 * Copyright © 2002-2023 by Thomas Thrien.
004 * All Rights Reserved.
005 * ============================================================================
006 *
007 * Licensed to the public under the agreements of the GNU Lesser General Public
008 * License, version 3.0 (the "License"). You may obtain a copy of the License at
009 *
010 *      http://www.gnu.org/licenses/lgpl.html
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
014 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
015 * License for the specific language governing permissions and limitations
016 * under the License.
017 */
018
019package org.tquadrat.foundation.util.stringconverter;
020
021import static java.util.Base64.getDecoder;
022import static java.util.Base64.getEncoder;
023import static org.apiguardian.api.API.Status.STABLE;
024import static org.tquadrat.foundation.lang.CommonConstants.ASCII;
025import static org.tquadrat.foundation.lang.Objects.isNull;
026
027import java.io.Serial;
028import java.util.Collection;
029import java.util.List;
030
031import org.apiguardian.api.API;
032import org.tquadrat.foundation.annotation.ClassVersion;
033import org.tquadrat.foundation.lang.StringConverter;
034
035/**
036 *  <p>{@summary The implementation of
037 *  {@link StringConverter}
038 *  for {@code byte} arrays.}</p>
039 *  <p>The output from
040 *  {@link #toString(byte[])}
041 *  will be in BASE64 format, encoded to
042 *  {@linkplain java.nio.charset.StandardCharsets#US_ASCII ASCII}.</p>
043 *  <p>Correspondingly,
044 *  {@link #fromString(CharSequence)}
045 *  expects an ASCII encoded BASE64 stream.</p>
046 *  <p>Both methods are using the BASE64 <i>basic</i> encoding scheme.</p>
047 *
048 *  @see java.util.Base64
049 *  @see java.util.Base64#getEncoder()
050 *  @see java.util.Base64#getDecoder()
051 *
052 *  @extauthor Thomas Thrien - thomas.thrien@tquadrat.org
053 *  @version $Id: ByteArrayStringConverter.java 1045 2023-02-07 23:09:17Z tquadrat $
054 *  @since 0.1.0
055 *
056 *  @UMLGraph.link
057 */
058@ClassVersion( sourceVersion = "$Id: ByteArrayStringConverter.java 1045 2023-02-07 23:09:17Z tquadrat $" )
059@API( status = STABLE, since = "0.1.0" )
060public final class ByteArrayStringConverter implements StringConverter<byte[]>
061{
062        /*------------------------*\
063    ====** Static Initialisations **===========================================
064        \*------------------------*/
065    /**
066     *  An instance of this class.
067     */
068    public static final ByteArrayStringConverter INSTANCE = new ByteArrayStringConverter();
069
070    /**
071     *  The serial version UID for objects of this class: {@value}.
072     *
073     *  @hidden
074     */
075    @Serial
076    private static final long serialVersionUID = 1L;
077
078        /*--------------*\
079    ====** Constructors **=====================================================
080        \*--------------*/
081    /**
082     *  Creates a new instance of {@code ByteArrayStringConverter}.
083     */
084    public ByteArrayStringConverter() {}
085
086        /*---------*\
087    ====** Methods **==========================================================
088        \*---------*/
089    /**
090     *  {@inheritDoc}
091     */
092    @Override
093    public final byte [] fromString( final CharSequence source ) throws IllegalArgumentException
094    {
095        final var retValue = isNull( source ) ? null : getDecoder().decode( source.toString().getBytes( ASCII ) );
096
097        //---* Done *----------------------------------------------------------
098        return retValue;
099    }   //  fromString()
100
101    /**
102     *  This method is used by the
103     *  {@link java.util.ServiceLoader}
104     *  to obtain the instance for this
105     *  {@link StringConverter}
106     *  implementation.
107     *
108     *  @return The instance for this {@code StringConverter} implementation.
109     */
110    public static final ByteArrayStringConverter provider() { return INSTANCE; }
111
112    /**
113     *  Provides the subject class for this converter.
114     *
115     *  @return The subject class.
116     */
117    @SuppressWarnings( "PublicMethodNotExposedInInterface" )
118    public final Collection<Class<?>> getSubjectClass() { return List.of( byte [].class ); }
119
120    /**
121     *  {@inheritDoc}
122     */
123    @Override
124    public final String toString( final byte [] source )
125    {
126        final var retValue = isNull( source ) ? null : new String( getEncoder().encode( source ), ASCII );
127
128        //---* Done *----------------------------------------------------------
129        return retValue;
130    }   //  toString()
131}
132//  class ByteArrayStringConverter
133
134/*
135 *  End of File
136 */