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

de.schlichtherle.key.PromptingKeyManager Maven / Gradle / Ivy

Go to download

TrueZIP is a Java based Virtual File System (VFS) to enable transparent, multi-threaded read/write access to archive files (ZIP, TAR etc.) as if they were directories. Archive files may be arbitrarily nested and the nesting level is only limited by heap and file system size.

The newest version!
/*
 * Copyright (C) 2006-2010 Schlichtherle IT Services
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package de.schlichtherle.key;

import java.lang.reflect.UndeclaredThrowableException;
import java.util.HashMap;
import java.util.Map;

/**
 * An abstract {@link KeyManager} which prompts the user for a key if required.
 * 

* This class maintains a map of user interface classes for the * {@code PromptingKeyProvider} class and each of its subclasses which * require an individual user interface. * The particular user interface classes are determined by a subclass of this * key manager. This enables the subclass to determine which user interface * technology should actually be used to prompt the user for a key. * For example, the implementation in the class * {@link de.schlichtherle.key.passwd.swing.PromptingKeyManager} uses Swing * to prompt the user for either a password or a key file. *

* Subclasses must use the method {@link #mapPromptingKeyProviderUIType} to * register a user interface class for a particular user interface class * identifier (the value returned by {@link PromptingKeyProvider#getUIClassID}). * This is best done in the constructor of the subclass. *

* Note that class loading and instantiation may happen in a JVM shutdown hook, * so class initializers and constructors must behave accordingly. * In particular, it's not permitted to construct or use a Swing GUI there. *

* This class is thread safe. * * @author Christian Schlichtherle * @version $Id$ * @since TrueZIP 6.0 */ public abstract class PromptingKeyManager extends KeyManager { private static volatile boolean prompting = true; private final Map providerUITypes = new HashMap(); /** * Constructs a new {@code PromptingKeyManager}. * This instance maps the following key provider types using * {@link KeyManager#mapKeyProviderType}: *

* * * * * * * * * * * * *
forKeyProviderTypeuseKeyProviderType
KeyProvider.classPromptingKeyProvider.class
AesKeyProvider.classPromptingAesKeyProvider.class
*/ public PromptingKeyManager() { mapKeyProviderType(KeyProvider.class, PromptingKeyProvider.class); mapKeyProviderType(AesKeyProvider.class, PromptingAesKeyProvider.class); } // // Static methods: // /** * Returns {@code true} if and only if prompting mode is enabled. * This is a class property. *

* Note that subclasses might add additional behaviour to both * {@link #isPrompting} and {@link #setPrompting} through the default * key manager instance (see {@link #getInstance}). * Regardless, an application may safely assume that * {@code isPrompting()} reflects the actual behaviour of the API * in this package although it may not reflect the parameter value of * the last call to {@code setPrompting(boolean)}. * * @return Whether or not the user will be prompted for a key if required. * * @see #setPrompting */ public static boolean isPrompting() { KeyManager manager = getInstance(); return manager instanceof PromptingKeyManager && ((PromptingKeyManager) manager).isPromptingImpl(); } /** * Called by {@link #isPrompting} on the default key manager instance in * order to implement its behaviour and allow subclasses to override it. * Subclasses should call the implementation in this class when * overriding this method. * * @see #setPromptingImpl * @see #getInstance * * @since TrueZIP 6.1 */ protected boolean isPromptingImpl() { return prompting; } /** * Enables or disables prompting mode. * If prompting mode is enabled, the user will be prompted for a key when * a {@link PromptingKeyProvider} is first requested to provide a key * for the respective resource. * If prompting mode is disabled, all attempts to prompt the user will * result in an {@link UnknownKeyException} until prompting mode is * enabled again. *

* This is a class property. *

* Note that subclasses might add additional behaviour to both * {@link #isPrompting} and {@link #setPrompting} through the default * key manager instance (see {@link #getInstance}). * Regardless, an application may safely assume that * {@code isPrompting()} reflects the actual behaviour of the API * in this package although it may not reflect the parameter value of * the last call to {@code setPrompting(boolean)}. * * @param prompting The value of the property {@code prompting}. * * @see #isPrompting */ public static void setPrompting(boolean prompting) { KeyManager manager = getInstance(); if (manager instanceof PromptingKeyManager) ((PromptingKeyManager) manager).setPromptingImpl(prompting); } /** * Called by {@link #isPrompting} on the default key manager instance in * order to implement its behaviour and allow subclasses to override it. * Subclasses should call the implementation in this class when * overriding this method. * * @see #isPromptingImpl * @see #getInstance * * @since TrueZIP 6.1 */ protected void setPromptingImpl(boolean prompting) { PromptingKeyManager.prompting = prompting; } static void ensurePrompting() throws KeyPromptingDisabledException { KeyManager manager = getInstance(); if (manager instanceof PromptingKeyManager) ((PromptingKeyManager) manager).ensurePromptingImpl(); } /** * Called by some methods in the {@link PromptingKeyProvider} class in * order to ensure that prompting mode is enabled. * This method may be overridden by subclasses in order to throw a more * detailed exception. *

* The implementation in this class is equivalent to: *

        if (!isPromptingImpl())
            throw new KeyPromptingDisabledException();
     * 
* * @since TrueZIP 6.1 */ protected void ensurePromptingImpl() throws KeyPromptingDisabledException { if (!isPromptingImpl()) throw new KeyPromptingDisabledException(); } /** * Resets all cancelled key prompts, forcing a new prompt on the next * call to {@link PromptingKeyProvider#getOpenKey()} or * {@link PromptingKeyProvider#getCreateKey()}. * Of course, this call only affects instances of * {@link PromptingKeyProvider}. */ public static void resetCancelledPrompts() { forEachKeyProvider(new KeyProviderCommand() { public void run(String resourceID, KeyProvider provider) { if (provider instanceof PromptingKeyProvider) ((PromptingKeyProvider) provider).resetCancelledPrompt(); } }); } // // Instance stuff: // /** * @deprecated Use {@link #mapPromptingKeyProviderUIType(String, Class) * mapPromptingKeyProviderUIType(uiClassID, uiClass)} instead. */ protected final void register( final String uiClassID, final Class uiClass) { mapPromptingKeyProviderUIType(uiClassID, uiClass); } /** * Subclasses must use this method to register a user interface class * for a particular user interface class identifier as returned by * {@link PromptingKeyProvider#getUIClassID}. * This is best done in the constructor of the subclass. * * @param uiClassID The identifier of the user interface class. * @param uiClass The user interface class. * This class must have a nullary constructor. * @see #getKeyProvider(String, Class) * @since TrueZIP 6.1 * @throws NullPointerException If any of the parameters is * {@code null}. * @throws IllegalArgumentException If {@code uiClass} does not * provide a public constructor with no parameters. */ protected synchronized final void mapPromptingKeyProviderUIType( final String uiClassID, final Class uiClass) { if (uiClassID == null) throw new NullPointerException("uiClassID"); if (!PromptingKeyProviderUI.class.isAssignableFrom(uiClass)) throw new IllegalArgumentException( uiClass.getName() + " must be PromptingKeyProviderUI or a subclass!"); try { uiClass.getConstructor(null); } catch (NoSuchMethodException noPublicNullaryConstructor) { final IllegalArgumentException iae = new IllegalArgumentException( uiClass.getName() + " (no public nullary constructor)"); iae.initCause(noPublicNullaryConstructor); throw iae; } providerUITypes.put(uiClassID, uiClass); } /** * Behaves like the super class implementation, but adds additional * behaviour in case the resulting key provider is an instance of * {@link PromptingKeyProvider}. * In this case, the appropriate user interface instance is determined * and installed in the key provider before it is returned. * * @see KeyManager#getKeyProvider(String, Class) */ public KeyProvider getKeyProvider( final String resourceID, final Class keyProviderType) throws NullPointerException, ClassCastException, IllegalArgumentException { final KeyProvider provider = super.getKeyProvider(resourceID, keyProviderType); if (provider instanceof PromptingKeyProvider) { final PromptingKeyProvider pkp = (PromptingKeyProvider) provider; pkp.setUI(getUI(pkp.getUIClassID())); } return provider; } private synchronized PromptingKeyProviderUI getUI(final String uiClassID) { final Object value = providerUITypes.get(uiClassID); final PromptingKeyProviderUI pkpui; if (value instanceof Class) { try { pkpui = (PromptingKeyProviderUI) ((Class) value).newInstance(); } catch (InstantiationException failure) { throw new UndeclaredThrowableException(failure); } catch (IllegalAccessException failure) { throw new UndeclaredThrowableException(failure); } providerUITypes.put(uiClassID, pkpui); } else if (value != null) { pkpui = (PromptingKeyProviderUI) value; } else { // value == null throw new IllegalArgumentException(uiClassID + " (unknown user interface for PromptingKeyProvider)"); } return pkpui; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy