All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.schlichtherle.truezip.key.sl.KeyManagerLocator Maven / Gradle / Ivy

Go to download

The file system driver family for ZIP and related archive file types. Add the JAR artifact of this module to the run time class path to make its file system drivers available for service location in the client API modules.

There is a newer version: 7.7.10
Show newest version
/*
 * Copyright (C) 2005-2013 Schlichtherle IT Services.
 * All rights reserved. Use is subject to license terms.
 */
package de.schlichtherle.truezip.key.sl;

import de.schlichtherle.truezip.fs.spi.FsDriverService;
import de.schlichtherle.truezip.key.AbstractKeyManagerProvider;
import de.schlichtherle.truezip.key.KeyManager;
import de.schlichtherle.truezip.key.spi.KeyManagerService;
import static de.schlichtherle.truezip.util.HashMaps.initialCapacity;
import de.schlichtherle.truezip.util.ServiceLocator;
import java.util.*;
import static java.util.logging.Level.CONFIG;
import static java.util.logging.Level.WARNING;
import java.util.logging.Logger;
import javax.annotation.concurrent.Immutable;

/**
 * Locates all key managers on the class path.
 * The map of key managers is populated by instantiating all classes
 * which are named in the resource files with the name
 * {@code "META-INF/services/de.schlichtherle.truezip.key.spi.KeyManagerService"}
 * on the class path by calling their public no-argument constructor.
 *
 * @see     KeyManagerService
 * @author  Christian Schlichtherle
 */
@Immutable
public final class KeyManagerLocator extends AbstractKeyManagerProvider {

    /** The singleton instance of this class. */
    public static final KeyManagerLocator SINGLETON = new KeyManagerLocator();

    /** You cannot instantiate this class. */
    private KeyManagerLocator() {
    }

    @Override
    public Map, KeyManager> get() {
        return Boot.MANAGERS;
    }

    /** A static data utility class used for lazy initialization. */
    private static final class Boot {
        static final Map, KeyManager> MANAGERS;
        static {
            final Logger logger = Logger.getLogger(
                    KeyManagerLocator.class.getName(),
                    KeyManagerLocator.class.getName());
            final Iterator
                    i = new ServiceLocator(KeyManagerLocator.class.getClassLoader())
                        .getServices(KeyManagerService.class);
            final Map, KeyManager>
                    sorted = new TreeMap, KeyManager>(
                        ClassComparator.INSTANCE);
            if (!i.hasNext())
                logger.log(WARNING, "null", FsDriverService.class);
            while (i.hasNext()) {
                KeyManagerService service = i.next();
                logger.log(CONFIG, "located", service);
                for (final Map.Entry, KeyManager> entry
                        : service.get().entrySet()) {
                    final Class type = entry.getKey();
                    final KeyManager newManager = entry.getValue();
                    if (null != type && null != newManager) {
                        final KeyManager oldManager = sorted.put(type, newManager);
                        if (null != oldManager
                                && oldManager.getPriority() > newManager.getPriority())
                            sorted.put(type, oldManager);
                    }
                }
            }
            final Map, KeyManager>
                    fast = new LinkedHashMap, KeyManager>(
                        initialCapacity(sorted.size()));
            for (final Map.Entry, KeyManager> entry : sorted.entrySet()) {
                final Class type = entry.getKey();
                final KeyManager manager = entry.getValue();
                logger.log(CONFIG, "mapping",
                        new Object[] { type, manager });
                fast.put(type, manager);
            }
            MANAGERS = Collections.unmodifiableMap(fast);
        }
    } // class Boot

    private static final class ClassComparator implements Comparator> {
        static final ClassComparator INSTANCE = new ClassComparator();

        @Override
        public int compare(Class o1, Class o2) {
            return o1.getName().compareTo(o2.getName());
        }
    } // ClassComparator
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy