/*
 * Copyright (c) 1998, 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 4190873
 * @summary Make sure provider instance can be removed from list of registered
 * providers, and "entrySet", "keySet", and "values" methods don't loop
 * indefinitely.
 */
import java.security.*;
import java.util.*;

public class RemoveProvider {

    public static void main(String[] args) throws Exception {

        // Add provider 1
        Provider p1 = new MyProvider("name1",1,"");
        Security.addProvider(p1);

        // Add provider 2
        Provider p2 = new MyProvider("name2",1,"");
        Security.addProvider(p2);

        // List all providers
        System.out.println("// List all providers");
        Provider[] provs = Security.getProviders();
        for (int i=0; i<provs.length; i++)
            System.out.println(provs[i].toString());

        // Remove one provider and list all remaining providers
        System.out.println("");
        System.out.println("// Remove one provider");
        Security.removeProvider("name1");
        provs = Security.getProviders();
        for (int i=0; i<provs.length; i++)
            System.out.println(provs[i].toString());

        // Iterate over the entrySet
        System.out.println("");
        System.out.println("// Iterate over entrySet");
        Map.Entry me = null;
        Set es = p1.entrySet();
        Iterator i = es.iterator();
        while (i.hasNext()) {
            me = (Map.Entry)i.next();
            System.out.println("Key: " + (String)me.getKey());
            System.out.println("Value: " + (String)me.getValue());
        }
        // Try to modify the backing Map, and catch the expected exception
        try {
            me.setValue("name1.mac");
            throw new Exception("Expected exception not thrown");
        } catch (UnsupportedOperationException uoe) {
            System.out.println("Expected exception caught");
        }

        // Iterate over the keySet, and try to remove one (should fail)
        System.out.println("");
        System.out.println("// Iterate over keySet");
        Object o = null;
        Set ks = p1.keySet();
        i = ks.iterator();
        while (i.hasNext()) {
            o = i.next();
            System.out.println((String)o);
        }
        try {
            ks.remove(o);
            throw new Exception("Expected exception not thrown");
        } catch (UnsupportedOperationException uoe) {
        }

        // Iterate over the map values
        System.out.println("");
        System.out.println("// Iterate over values");
        Collection c = p1.values();
        i = c.iterator();
        while (i.hasNext()) {
            System.out.println((String)i.next());
        }

        // Modify provider and make sure changes are reflected in
        // existing entrySet (i.e., make sure entrySet is "live").
        // First, add entry to provider.
        System.out.println("");
        System.out.println("// Add 'Cipher' entry to provider");
        p1.put("Cipher", "name1.des");
        //  entrySet
        i = es.iterator();
        boolean found = false;
        while (i.hasNext()) {
            me = (Map.Entry)i.next();
            System.out.println("Key: " + (String)me.getKey());
            System.out.println("Value: " + (String)me.getValue());
            if (((String)me.getKey()).equals("Cipher"))
                found = true;
        }
        if (!found)
            throw new Exception("EntrySet not live");
        // keySet
        i = ks.iterator();
        while (i.hasNext()) {
            o = i.next();
            System.out.println((String)o);
        }
        // collection
        i = c.iterator();
        while (i.hasNext()) {
            System.out.println((String)i.next());
        }

        // Remove entry from provider
        System.out.println("");
        System.out.println("// Remove 'Digest' entry from provider");
        p1.remove("Digest");
        // entrySet
        i = es.iterator();
        while (i.hasNext()) {
            me = (Map.Entry)i.next();
            System.out.println("Key: " + (String)me.getKey());
            System.out.println("Value: " + (String)me.getValue());
        }
        // keySet
        i = ks.iterator();
        while (i.hasNext()) {
            o = i.next();
            System.out.println((String)o);
        }
        // collection
        i = c.iterator();
        while (i.hasNext()) {
            System.out.println((String)i.next());
        }

        // Retrieve new entrySet and make sure the backing Map cannot be
        // mofified
        es = p1.entrySet();
        i = es.iterator();
        while (i.hasNext()) {
            me = (Map.Entry)i.next();
            System.out.println("Key: " + (String)me.getKey());
            System.out.println("Value: " + (String)me.getValue());
        }
        try {
            me.setValue("name1.mac");
            throw new Exception("Expected exception not thrown");
        } catch (UnsupportedOperationException uoe) {
            System.out.println("Expected exception caught");
        }
    }
}

class MyProvider extends Provider {
    public MyProvider(String name, double version, String info) {
        super(name, version, info);
        put("Signature", name+".signature");
        put("Digest", name+".digest");
    }
}
