1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5package org.chromium.chrome.browser.identity;
6
7import org.chromium.base.VisibleForTesting;
8
9import java.util.HashMap;
10import java.util.Map;
11
12/**
13 * Factory for setting and retrieving instances of {@link UniqueIdentificationGenerator}s.
14 * <p/>
15 * A generator must always be set for a generator type before it is asked for. A generator type
16 * is any string you want to use for your generator. It is typically defined as a public static
17 * field in the generator itself.
18 */
19public final class UniqueIdentificationGeneratorFactory {
20    private static final Object LOCK = new Object();
21    private static final Map<String, UniqueIdentificationGenerator> GENERATOR_MAP =
22            new HashMap<String, UniqueIdentificationGenerator>();
23
24    private UniqueIdentificationGeneratorFactory() {
25    }
26
27    /**
28     * Returns a UniqueIdentificationGenerator if it exists, else throws IllegalArgumentException.
29     *
30     * @param generatorType the generator type you want
31     * @return a unique ID generator
32     */
33    public static UniqueIdentificationGenerator getInstance(String generatorType) {
34        synchronized (LOCK) {
35            if (!GENERATOR_MAP.containsKey(generatorType)) {
36                throw new IllegalArgumentException("Unknown generator type " + generatorType);
37            }
38            return GENERATOR_MAP.get(generatorType);
39        }
40    }
41
42    /**
43     * During startup of the application, and before any calls to
44     * {@link #getInstance(String)} you must add all supported generators
45     * to this factory.
46     *
47     * @param generatorType the type of generator this is. Must be a unique string.
48     * @param gen           the generator.
49     * @param force         if set to true, will override any existing generator for this type. Else
50     *                      discards calls where a generator exists.
51     */
52    @VisibleForTesting
53    public static void registerGenerator(String generatorType, UniqueIdentificationGenerator gen,
54                                         boolean force) {
55        synchronized (LOCK) {
56            if (GENERATOR_MAP.containsKey(generatorType) && !force) {
57                return;
58            }
59            GENERATOR_MAP.put(generatorType, gen);
60        }
61    }
62
63    @VisibleForTesting
64    public static void clearGeneratorMapForTest() {
65        synchronized (LOCK) {
66            GENERATOR_MAP.clear();
67        }
68    }
69}
70