EMMA Coverage Report (generated Wed Oct 03 05:00:03 CEST 2012)
[all classes][org.jdtaus.core.nio.util]

COVERAGE SUMMARY FOR SOURCE FILE [Charsets.java]

nameclass, %method, %block, %line, %
Charsets.java100% (1/1)67%  (4/6)45%  (207/457)44%  (49.2/111)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Charsets100% (1/1)67%  (4/6)45%  (207/457)44%  (49.2/111)
Charsets (): void 0%   (0/1)0%   (0/3)0%   (0/2)
decode (byte [], int, int, String): String 0%   (0/1)0%   (0/103)0%   (0/26)
decode (byte [], String): String 100% (1/1)36%  (27/75)36%  (8/22)
encode (String, String): byte [] 100% (1/1)48%  (41/86)46%  (11/24)
getCharset (String): Charset 100% (1/1)71%  (118/166)80%  (27.4/34)
<static initializer> 100% (1/1)88%  (21/24)96%  (2.9/3)

1/*
2 *  jDTAUS Core Utilities
3 *  Copyright (C) 2005 Christian Schulte
4 *  <cs@schulte.it>
5 *
6 *  This library is free software; you can redistribute it and/or
7 *  modify it under the terms of the GNU Lesser General Public
8 *  License as published by the Free Software Foundation; either
9 *  version 2.1 of the License, or any later version.
10 *
11 *  This library is distributed in the hope that it will be useful,
12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 *  Lesser General Public License for more details.
15 *
16 *  You should have received a copy of the GNU Lesser General Public
17 *  License along with this library; if not, write to the Free Software
18 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19 *
20 */
21package org.jdtaus.core.nio.util;
22 
23import java.io.BufferedReader;
24import java.io.IOException;
25import java.io.InputStream;
26import java.io.InputStreamReader;
27import java.net.URL;
28import java.nio.ByteBuffer;
29import java.nio.CharBuffer;
30import java.nio.charset.Charset;
31import java.nio.charset.spi.CharsetProvider;
32import java.util.Enumeration;
33import java.util.HashMap;
34import java.util.Iterator;
35import java.util.LinkedList;
36import java.util.List;
37import java.util.Map;
38 
39/**
40 * Charset coder and decoder utility.
41 * <p>This class extends the former charset provider implementations which
42 * cannot be used in every environment (e.g. WebStart, Maven) without
43 * installation in the JRE extensions directory where they are available to the
44 * system classloader. It uses the same service provider files as the
45 * platform implementation ({@code java.nio.charset.spi.CharsetProvider}) but
46 * is capable of using the current thread's classloader before falling back
47 * to the system classloader for loading {@code CharsetProvider} classes.</p>
48 *
49 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
50 * @version $JDTAUS: Charsets.java 8641 2012-09-27 06:45:17Z schulte $
51 */
52public class Charsets
53{
54    //--Charsets----------------------------------------------------------------
55 
56    /** Cached {@code CharsetProvider} instances. */
57    private static final List providers = new LinkedList();
58 
59    /** Cached {@code Charset} instances by name. */
60    private static final Map charsets = new HashMap( 100 );
61 
62    /** Private constructor. */
63    private Charsets()
64    {
65        super();
66    }
67 
68    /**
69     * Gets a charset for the given name.
70     *
71     * @param name the name of the charset to return.
72     *
73     * @return a {@code Charset} corresponding to {@code name} or {@code null}
74     * if no such {@code Charset} is available.
75     *
76     * @throws IOException if reading the service provider files fails.
77     * @throws ClassNotFoundException if a service provider file defines
78     * a class which cannot be loaded.
79     * @throws InstantiationException if creating an instance of a
80     * {@code CharsetProvider} fails.
81     * @throws IllegalAccessException if a {@code CharsetProvider} class
82     * does not define a public no-arg constructor.
83     * @throws java.nio.charset.IllegalCharsetNameException if {@code name} is
84     * no valid charset name.
85     * @throws java.nio.charset.UnsupportedCharsetException if {@code name} is
86     * not supported.
87     */
88    private static Charset getCharset( final String name )
89        throws IOException, ClassNotFoundException, InstantiationException,
90               IllegalAccessException
91    {
92        // Populate the provider list with available providers if it is empty.
93        if ( providers.size() == 0 )
94        {
95            synchronized ( Charsets.class )
96            {
97                // Use the current thread's context classloader if available or
98                // fall back to the system classloader.
99                ClassLoader classLoader = Thread.currentThread().
100                    getContextClassLoader();
101 
102                if ( classLoader == null )
103                {
104                    classLoader = ClassLoader.getSystemClassLoader();
105                }
106 
107                assert classLoader != null :
108                    "Expected system classloader to always be available.";
109 
110                // Read all service provider files and load all defined
111                // provider classes.
112                final Enumeration providerFiles = classLoader.getResources(
113                    "META-INF/services/java.nio.charset.spi.CharsetProvider" );
114 
115                if ( providerFiles != null )
116                {
117                    for (; providerFiles.hasMoreElements();)
118                    {
119                        final URL url = ( URL ) providerFiles.nextElement();
120                        final InputStream in = url.openStream();
121 
122                        try
123                        {
124                            String line;
125                            final BufferedReader reader = new BufferedReader(
126                                new InputStreamReader( in, "UTF-8" ) );
127 
128                            while ( ( line = reader.readLine() ) != null )
129                            {
130                                // Check that the line denotes a valid Java
131                                // classname and load that class using
132                                // reflection.
133                                if ( line.indexOf( '#' ) < 0 )
134                                {
135                                    providers.add( classLoader.loadClass( line ).
136                                                   newInstance() );
137 
138                                }
139                            }
140                        }
141                        finally
142                        {
143                            in.close();
144                        }
145                    }
146                }
147            }
148        }
149 
150        // Search cached charsets.
151        Charset charset = ( Charset ) charsets.get( name );
152        if ( charset == null )
153        {
154            synchronized ( Charsets.class )
155            {
156                // Search all available providers for a charset matching "name".
157                for ( Iterator it = providers.iterator(); it.hasNext();)
158                {
159                    charset =
160                        ( ( CharsetProvider ) it.next() ).charsetForName( name );
161 
162                    if ( charset != null )
163                    {
164                        charsets.put( name, charset );
165                        break;
166                    }
167                }
168            }
169        }
170 
171        // Fall back to platform charsets if nothing is found so far.
172        if ( charset == null )
173        {
174            synchronized ( Charsets.class )
175            {
176                charset = Charset.forName( name );
177                charsets.put( name, charset );
178            }
179        }
180 
181        return charset;
182    }
183 
184    /**
185     * Encodes a given string to an array of bytes representing the characters
186     * of the string in a given charset.
187     *
188     * @param str the string to encode.
189     * @param charset the name of the charset to use.
190     *
191     * @throws NullPointerException if {@code str} or {@code charset} is
192     * {@code null}.
193     * @throws java.nio.charset.IllegalCharsetNameException if {@code charset}
194     * is no valid charset name.
195     * @throws java.nio.charset.UnsupportedCharsetException if {@code charset}
196     * is not supported.
197     */
198    public static byte[] encode( final String str, final String charset )
199    {
200        if ( str == null )
201        {
202            throw new NullPointerException( "str" );
203        }
204        if ( charset == null )
205        {
206            throw new NullPointerException( "charset" );
207        }
208 
209        final byte[] ret;
210        try
211        {
212            final Charset cset = Charsets.getCharset( charset );
213            final ByteBuffer buf = cset.encode( str );
214 
215            if ( buf.hasArray() )
216            {
217                if ( buf.array().length == buf.limit() )
218                {
219                    ret = buf.array();
220                }
221                else
222                {
223                    ret = new byte[ buf.limit() ];
224                    System.arraycopy( buf.array(), buf.arrayOffset(),
225                                      ret, 0, ret.length );
226 
227                }
228            }
229            else
230            {
231                ret = new byte[ buf.limit() ];
232                buf.rewind();
233                buf.get( ret );
234            }
235        }
236        catch ( ClassNotFoundException e )
237        {
238            throw new AssertionError( e );
239        }
240        catch ( InstantiationException e )
241        {
242            throw new AssertionError( e );
243        }
244        catch ( IllegalAccessException e )
245        {
246            throw new AssertionError( e );
247        }
248        catch ( IOException e )
249        {
250            throw new AssertionError( e );
251        }
252 
253        return ret;
254    }
255 
256    /**
257     * Decodes the bytes of a given array to a string.
258     *
259     * @param bytes the bytes to decode.
260     * @param charset the name of the charset to use.
261     *
262     * @throws NullPointerException if {@code bytes} or {@code charset} is
263     * {@code null}.
264     * @throws java.nio.charset.IllegalCharsetNameException if {@code charset}
265     * is no valid charset name.
266     * @throws java.nio.charset.UnsupportedCharsetException if {@code charset}
267     * is not supported.
268     */
269    public static String decode( final byte[] bytes, final String charset )
270    {
271        if ( bytes == null )
272        {
273            throw new NullPointerException( "bytes" );
274        }
275        if ( charset == null )
276        {
277            throw new NullPointerException( "charset" );
278        }
279 
280        final String ret;
281        try
282        {
283            final Charset cset = Charsets.getCharset( charset );
284            final CharBuffer buf = cset.decode( ByteBuffer.wrap( bytes ) );
285 
286            if ( buf.hasArray() )
287            {
288                ret = String.valueOf( buf.array(), buf.arrayOffset(),
289                                      buf.length() );
290 
291            }
292            else
293            {
294                final char[] c = new char[ buf.length() ];
295                buf.rewind();
296                buf.get( c );
297                ret = String.valueOf( c );
298            }
299        }
300        catch ( ClassNotFoundException e )
301        {
302            throw new AssertionError( e );
303        }
304        catch ( InstantiationException e )
305        {
306            throw new AssertionError( e );
307        }
308        catch ( IllegalAccessException e )
309        {
310            throw new AssertionError( e );
311        }
312        catch ( IOException e )
313        {
314            throw new AssertionError( e );
315        }
316 
317        return ret;
318    }
319 
320    /**
321     * Decodes the bytes of a given array to a string.
322     *
323     * @param bytes the bytes to decode.
324     * @param off the offset from where to start decoding.
325     * @param count the number of bytes to decode starting at {@code offset}.
326     * @param charset the name of the charset to use.
327     *
328     * @throws NullPointerException if {@code bytes} or {@code charset} is
329     * {@code null}.
330     * @throws IndexOutOfBoundsException if {@code off} is negative or greater
331     * than the length of {@code bytes} or {@code off + count} is negative or
332     * greater than the length of {@code bytes}.
333     * @throws java.nio.charset.IllegalCharsetNameException if {@code charset}
334     * is no valid charset name.
335     * @throws java.nio.charset.UnsupportedCharsetException if {@code charset}
336     * is not supported.
337     */
338    public static String decode( final byte[] bytes, final int off,
339                                   final int count, final String charset )
340    {
341        if ( bytes == null )
342        {
343            throw new NullPointerException( "bytes" );
344        }
345        if ( charset == null )
346        {
347            throw new NullPointerException( "charset" );
348        }
349        if ( off < 0 || off >= bytes.length )
350        {
351            throw new ArrayIndexOutOfBoundsException( off );
352        }
353        if ( count < 0 || off + count >= bytes.length )
354        {
355            throw new ArrayIndexOutOfBoundsException( count + off );
356        }
357 
358        final String ret;
359        try
360        {
361            final Charset cset = Charsets.getCharset( charset );
362            final CharBuffer buf = cset.decode(
363                ByteBuffer.wrap( bytes, off, count ) );
364 
365            if ( buf.hasArray() )
366            {
367                ret = String.valueOf( buf.array(), buf.arrayOffset(),
368                                      buf.length() );
369 
370            }
371            else
372            {
373                final char[] c = new char[ buf.length() ];
374                buf.rewind();
375                buf.get( c );
376                ret = String.valueOf( c );
377            }
378        }
379        catch ( ClassNotFoundException e )
380        {
381            throw new AssertionError( e );
382        }
383        catch ( InstantiationException e )
384        {
385            throw new AssertionError( e );
386        }
387        catch ( IllegalAccessException e )
388        {
389            throw new AssertionError( e );
390        }
391        catch ( IOException e )
392        {
393            throw new AssertionError( e );
394        }
395 
396        return ret;
397    }
398 
399    //----------------------------------------------------------------Charsets--
400}

[all classes][org.jdtaus.core.nio.util]
EMMA 2.1.5320 (stable) (C) Vladimir Roubtsov