/*
 * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
/*
 * @test
 * @bug 6204853
 * @summary tests PropertyResourceBundle(Reader) constructor.
 */

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.PropertyResourceBundle;

public final class Bug6204853 {

    public Bug6204853() {
        try {
            String srcDir = System.getProperty("test.src", ".");
            FileInputStream  fis8859_1 =
                new FileInputStream(new File(srcDir, "Bug6204853.properties"));
            FileInputStream fisUtf8 =
                new FileInputStream(new File(srcDir, "Bug6204853_Utf8.properties"));
            InputStreamReader isrUtf8 = new InputStreamReader(fisUtf8, "UTF-8");

            PropertyResourceBundle bundleUtf8 = new PropertyResourceBundle(isrUtf8);
            PropertyResourceBundle bundle = new PropertyResourceBundle(fis8859_1);

            String[] arrayUtf8 = createKeyValueArray(bundleUtf8);
            String[] array = createKeyValueArray(bundle);

            isrUtf8.close();
            fisUtf8.close();
            fis8859_1.close();

            if (!Arrays.equals(arrayUtf8, array)) {
                throw new RuntimeException("PropertyResourceBundle constructed from a UTF-8 encoded property file is not equal to the one constructed from ISO-8859-1 encoded property file.");
            }
        } catch (FileNotFoundException fnfe) {
            throw new RuntimeException(fnfe);
        } catch (IOException ioe) {
            throw new RuntimeException(ioe);
        }
    }

    private final String[] createKeyValueArray(PropertyResourceBundle b) {
        List<String> keyValueList = new ArrayList<String>();
        StringBuilder sb = new StringBuilder();

        for (String key : b.keySet()) {
            sb.setLength(0);
            sb.append(key);
            sb.append(" = ");
            sb.append(b.getString(key));
            keyValueList.add(sb.toString());
        }

        String[] keyValueArray = keyValueList.toArray(new String[0]);
        Arrays.sort(keyValueArray);
        return keyValueArray;
    }

    public final static void main(String[] args) {
        new Bug6204853();
    }
}
