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

org.opensaml.xml.encryption.ChainingEncryptedKeyResolver Maven / Gradle / Ivy

Go to download

XMLTooling-J is a low-level library that may be used to construct libraries that allow developers to work with XML in a Java beans manner.

There is a newer version: 1.4.4
Show newest version
/*
 * Copyright [2007] [University Corporation for Advanced Internet Development, Inc.]
 *
 * 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 org.opensaml.xml.encryption;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * An implementation of {@link EncryptedKeyResolver} which chains multiple other resolver implementations together,
 * calling them in the order specified in the resolver list.
 */
public class ChainingEncryptedKeyResolver extends AbstractEncryptedKeyResolver {

    /** The list of resolvers which form the resolution chain. */
    private final List resolvers;

    /** Class logger. */
    private final Logger log = LoggerFactory.getLogger(ChainingEncryptedKeyResolver.class);

    /** Constructor. */
    public ChainingEncryptedKeyResolver() {
        resolvers = new ArrayList();
    }

    /**
     * Get the list of resolvers which form the resolution chain.
     * 
     * @return a list of EncryptedKeyResolver instances
     */
    public List getResolverChain() {
        return resolvers;
    }

    /** {@inheritDoc} */
    public Iterable resolve(EncryptedData encryptedData) {
        if (resolvers.isEmpty()) {
            log.warn("Chaining encrypted key resolver resolution was attempted with an empty resolver chain");
            throw new IllegalStateException("The resolver chain is empty");
        }
        return new ChainingIterable(this, encryptedData);
    }

    /**
     * Implementation of {@link Iterable} to be returned by {@link ChainingEncryptedKeyResolver}.
     */
    public class ChainingIterable implements Iterable {

        /** The chaining encrypted key resolver which owns this instance. */
        private ChainingEncryptedKeyResolver parent;

        /** The EncryptedData context for resolution. */
        private EncryptedData encryptedData;

        /**
         * Constructor.
         * 
         * @param resolver the ChainingEncryptedKeyResolver parent
         * @param encData the EncryptedData context for resolution
         */
        public ChainingIterable(ChainingEncryptedKeyResolver resolver, EncryptedData encData) {
            parent = resolver;
            encryptedData = encData;
        }

        /** {@inheritDoc} */
        public Iterator iterator() {
            return new ChainingIterator(parent, encryptedData);
        }

    }

    /**
     * Implementation of {@link Iterator} to be (indirectly) returned by {@link ChainingEncryptedKeyResolver}.
     * 
     */
    public class ChainingIterator implements Iterator {

        /** Class logger. */
        private final Logger log = LoggerFactory.getLogger(ChainingEncryptedKeyResolver.ChainingIterator.class);

        /** The chaining encrypted key resolver which owns this instance. */
        private ChainingEncryptedKeyResolver parent;

        /** The EncryptedData context for resolution. */
        private EncryptedData encryptedData;

        /** The iterator over resolvers in the chain. */
        private Iterator resolverIterator;

        /** The iterator over EncryptedKey instances from the current resolver. */
        private Iterator keyIterator;

        /** The current resolver which is returning encrypted keys. */
        private EncryptedKeyResolver currentResolver;

        /** The next encrypted key that is safe to return. */
        private EncryptedKey nextKey;

        /**
         * Constructor.
         * 
         * @param resolver the ChainingEncryptedKeyResolver parent
         * @param encData the EncryptedData context for resolution
         */
        public ChainingIterator(ChainingEncryptedKeyResolver resolver, EncryptedData encData) {
            parent = resolver;
            encryptedData = encData;
            resolverIterator = parent.getResolverChain().iterator();
            keyIterator = getNextKeyIterator();
            nextKey = null;
        }

        /** {@inheritDoc} */
        public boolean hasNext() {
            if (nextKey != null) {
                return true;
            }
            nextKey = getNextKey();
            if (nextKey != null) {
                return true;
            }
            return false;
        }

        /** {@inheritDoc} */
        public EncryptedKey next() {
            EncryptedKey tempKey;
            if (nextKey != null) {
                tempKey = nextKey;
                nextKey = null;
                return tempKey;
            }
            tempKey = getNextKey();
            if (tempKey != null) {
                return tempKey;
            } else {
                throw new NoSuchElementException("No more EncryptedKey elements are available");
            }
        }

        /** {@inheritDoc} */
        public void remove() {
            throw new UnsupportedOperationException("Remove operation is not supported by this iterator");
        }

        /**
         * Get the iterator from the next resolver in the chain.
         * 
         * @return an iterator of encrypted keys
         */
        private Iterator getNextKeyIterator() {
            if (resolverIterator.hasNext()) {
                currentResolver = resolverIterator.next();
                log.debug("Getting key iterator from next resolver: {}", currentResolver.getClass().toString());
                return currentResolver.resolve(encryptedData).iterator();
            } else {
                log.debug("No more resolvers available in the resolver chain");
                currentResolver = null;
                return null;
            }
        }

        /**
         * Get the next encrypted key that will be returned by this iterator.
         * 
         * @return the next encrypted key to return
         */
        private EncryptedKey getNextKey() {
            EncryptedKey tempKey;

            if (keyIterator != null) {
                while (keyIterator.hasNext()) {
                    tempKey = keyIterator.next();
                    if (parent.matchRecipient(tempKey.getRecipient())) {
                        log.debug("Found matching encrypted key: {}", tempKey.toString());
                        return tempKey;
                    }
                }
            }

            keyIterator = getNextKeyIterator();
            while (keyIterator != null) {
                while (keyIterator.hasNext()) {
                    tempKey = keyIterator.next();
                    if (parent.matchRecipient(tempKey.getRecipient())) {
                        log.debug("Found matching encrypted key: {}", tempKey.toString());
                        return tempKey;
                    }
                }
                keyIterator = getNextKeyIterator();
            }

            return null;
        }

    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy