org.codice.ddf.catalog.ui.security.ShareableMetacardImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.codice.ddf.catalog.ui.security.ShareableMetacardImpl.java

Source

/**
 * Copyright (c) Codice Foundation
 *
 * <p>This is free software: you can redistribute it and/or modify it under the terms of the GNU
 * Lesser General Public License as published by the Free Software Foundation, either version 3 of
 * the License, or any later version.
 *
 * <p>This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details. A copy of the GNU Lesser General Public
 * License is distributed along with this program and can be found at
 * <http://www.gnu.org/licenses/lgpl.html>.
 */
package org.codice.ddf.catalog.ui.security;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Sets;
import ddf.catalog.data.Attribute;
import ddf.catalog.data.AttributeDescriptor;
import ddf.catalog.data.Metacard;
import ddf.catalog.data.MetacardType;
import ddf.catalog.data.impl.MetacardImpl;
import ddf.catalog.data.impl.MetacardTypeImpl;
import ddf.catalog.data.impl.types.CoreAttributes;
import ddf.catalog.data.impl.types.SecurityAttributes;
import ddf.catalog.data.types.Core;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.codice.ddf.catalog.ui.forms.data.AttributeGroupMetacard;
import org.codice.ddf.catalog.ui.forms.data.QueryTemplateMetacard;
import org.codice.ddf.catalog.ui.metacard.workspace.WorkspaceMetacardImpl;

/**
 * Provides a set of operations that can be performed on {@link Metacard}s that support sharing. Use
 * {@link #canShare(Metacard)} to determine if a {@link Metacard} supports sharing, and {@link
 * #createOrThrow(Metacard)} to obtain and validate an instance of this class.
 */
public class ShareableMetacardImpl extends MetacardImpl {

    protected ShareableMetacardImpl(MetacardType type) {
        super(type);
    }

    protected ShareableMetacardImpl(Metacard metacard) {
        super(metacard);
    }

    @VisibleForTesting
    ShareableMetacardImpl() {
        super(new MetacardTypeImpl("metacard.sharing",
                Arrays.asList(new CoreAttributes(), new SecurityAttributes())));
    }

    @VisibleForTesting
    ShareableMetacardImpl(String id) {
        this();
        setId(id);
    }

    /**
     * Check if a given metacard is a shareable metacard by checking the presence of security
     * attributes.
     *
     * @param metacard the metacard to check.
     * @return true if the provided metacard is a shareable metacard, false otherwise.
     */
    public static boolean canShare(Metacard metacard) {
        return metacard != null
                && (WorkspaceMetacardImpl.isWorkspaceMetacard(metacard)
                        || QueryTemplateMetacard.isQueryTemplateMetacard(metacard)
                        || AttributeGroupMetacard.isAttributeGroupMetacard(metacard))
                && metacard.getMetacardType().getAttributeDescriptors().stream().map(AttributeDescriptor::getName)
                        .anyMatch(attr -> Objects.equals(SecurityAttributes.ACCESS_GROUPS, attr))
                && metacard.getMetacardType().getAttributeDescriptors().stream().map(AttributeDescriptor::getName)
                        .anyMatch(attr -> Objects.equals(SecurityAttributes.ACCESS_INDIVIDUALS, attr));
    }

    /**
     * Determine if a {@link Metacard} can support sharing. If so, decorate it as a {@link
     * ShareableMetacardImpl}.
     *
     * @param metacard the metacard to decorate.
     * @return a {@link ShareableMetacardImpl} that exposes sharing operations on the decorated
     *     metacard.
     * @throws IllegalArgumentException if the provided {@link Metacard} does not support sharing.
     */
    public static ShareableMetacardImpl createOrThrow(Metacard metacard) {
        if (!canShare(metacard)) {
            throw new IllegalArgumentException("Metacard does not support sharing");
        }
        return new ShareableMetacardImpl(metacard);
    }

    public static Optional<ShareableMetacardImpl> create(Metacard metacard) {
        if (!canShare(metacard)) {
            return Optional.empty();
        }
        return Optional.of(new ShareableMetacardImpl(metacard));
    }

    @VisibleForTesting
    static ShareableMetacardImpl create(Map<String, Serializable> attributes) {
        ShareableMetacardImpl shareableMetaCard = new ShareableMetacardImpl();
        attributes.entrySet().stream()
                .forEach(entry -> shareableMetaCard.setAttribute(entry.getKey(), entry.getValue()));

        return shareableMetaCard;
    }

    /**
     * Get a copy of a shareable metacard.
     *
     * @param metacard the metacard to copy.
     * @return a {@link ShareableMetacardImpl} with all the attributes of the original.
     */
    @VisibleForTesting
    static ShareableMetacardImpl clone(Metacard metacard) {
        ShareableMetacardImpl shareableMetacard = new ShareableMetacardImpl();
        metacard.getMetacardType().getAttributeDescriptors().stream()
                .forEach(descriptor -> shareableMetacard.setAttribute(metacard.getAttribute(descriptor.getName())));

        return shareableMetacard;
    }

    /**
     * Compute the symmetric difference between the access individuals
     *
     * @param metacard - metacard to diff against
     */
    public Set<String> diffSharingAccessIndividuals(Metacard metacard) {
        return Sets.symmetricDifference(getAccessIndividuals(), createOrThrow(metacard).getAccessIndividuals());
    }

    /**
     * Compute the symmetric difference between the access groups
     *
     * @param metacard - metacard to diff against
     */
    public Set<String> diffSharingAccessGroups(Metacard metacard) {
        return Sets.symmetricDifference(getAccessGroups(), createOrThrow(metacard).getAccessGroups());
    }

    protected List<String> getValuesOrEmpty(String attributeName) {
        Attribute attribute = getAttribute(attributeName);
        if (attribute != null) {
            return attribute.getValues().stream().map(String::valueOf).collect(Collectors.toList());
        }
        return Collections.emptyList();
    }

    public String getOwner() {
        List<String> values = getValuesOrEmpty(Core.METACARD_OWNER);
        if (!values.isEmpty()) {
            return values.get(0);
        }
        return null;
    }

    public ShareableMetacardImpl setOwner(String email) {
        setAttribute(Core.METACARD_OWNER, email);
        return this;
    }

    public Set<String> getAccessIndividuals() {
        return new HashSet<>(getValuesOrEmpty(SecurityAttributes.ACCESS_INDIVIDUALS));
    }

    public Set<String> getAccessGroups() {
        return new HashSet<>(getValuesOrEmpty(SecurityAttributes.ACCESS_GROUPS));
    }

    public ShareableMetacardImpl setAccessIndividuals(Set<String> accessIndividuals) {
        setAttribute(SecurityAttributes.ACCESS_INDIVIDUALS, new ArrayList<>(accessIndividuals));
        return this;
    }

    public ShareableMetacardImpl setAccessGroups(Set<String> accessGroups) {
        setAttribute(SecurityAttributes.ACCESS_GROUPS, new ArrayList<>(accessGroups));
        return this;
    }
}