001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2015 ForgeRock AS.
015 */
016package org.forgerock.audit.filter;
017
018import java.util.Collection;
019import java.util.LinkedHashMap;
020import java.util.LinkedList;
021import java.util.List;
022import java.util.Map;
023
024import org.forgerock.audit.AuditException;
025import org.forgerock.audit.filter.Filters.FilterNames;
026import org.forgerock.json.JsonValue;
027import org.forgerock.util.Reject;
028
029/**
030 * A builder that builds a filter chain.
031 */
032public class FilterChainBuilder {
033    private Map<String, FilterPolicy> policies;
034    private List<String> auditTopics;
035
036    /**
037     * Adds the topics this filter chain is for.
038     * @param auditTopics The topics.
039     * @return This FilterChainBuilder.
040     */
041    public FilterChainBuilder withAuditTopics(final Collection<String> auditTopics) {
042        Reject.ifNull(auditTopics);
043        this.auditTopics = new LinkedList<>(auditTopics);
044        return this;
045    }
046
047    /**
048     * Adds the policies to chain together. The expected input would be a map with the key being
049     * the {@link FilterNames}, and the value the {@link FilterPolicy} for that given filter.
050     * @param policies The policies.
051     * @return This FilterChainBuilder.
052     */
053    public FilterChainBuilder withPolicies(final Map<String, FilterPolicy> policies) {
054        Reject.ifNull(policies);
055        this.policies = new LinkedHashMap<>(policies);
056        return this;
057    }
058
059    /**
060     * Builds the FilterChain.
061     * @return The FilterChain as a {@link Filter}.
062     */
063    public Filter build() {
064        final List<Filter> filters = new LinkedList<>();
065        // create Filters
066        if (policies != null && auditTopics != null) {
067            for (final Map.Entry<String, FilterPolicy> policyEntry : policies.entrySet()) {
068                try {
069                    filters.add(Filters.newFilter(policyEntry.getKey(), auditTopics, policyEntry.getValue()));
070                } catch (AuditException e) {
071                    // Do nothing. The exception has been logged.
072                }
073            }
074        }
075        return new FilterChain(filters);
076    }
077
078    /**
079     * Chains together multiple filters and runs them all.
080     */
081    public static class FilterChain implements Filter {
082        private final List<Filter> filters;
083
084        /**
085         * Creates a filter chain from a given list of filters.
086         * @param filters The list of filters to chain.
087         */
088        FilterChain(List<Filter> filters) {
089            this.filters = new LinkedList<>(filters);
090        }
091
092        /**
093         * Runs the filters in the filter chain.
094         * {@inheritDoc}
095         */
096        @Override
097        public void doFilter(String auditTopic, JsonValue auditEvent) {
098            for (final Filter filter: filters) {
099                filter.doFilter(auditTopic, auditEvent);
100            }
101        }
102    }
103}