fr.gael.dhus.olingo.v1.map.FunctionalMap.java Source code

Java tutorial

Introduction

Here is the source code for fr.gael.dhus.olingo.v1.map.FunctionalMap.java

Source

/*
 * Data Hub Service (DHuS) - For Space data distribution.
 * Copyright (C) 2016 GAEL Systems
 *
 * This file is part of DHuS software sources.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package fr.gael.dhus.olingo.v1.map;

import fr.gael.dhus.olingo.v1.FunctionalVisitor;
import fr.gael.dhus.olingo.v1.visitor.ExecutableExpressionTree;
import fr.gael.dhus.util.functional.collect.SortedMap;

import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import org.apache.commons.collections4.functors.ConstantFactory;

import org.apache.olingo.odata2.api.exception.ODataApplicationException;
import org.apache.olingo.odata2.api.uri.expression.ExceptionVisitExpression;

/**
 * This class is the base class to create a read-only, sortable, filterable Map view on another map.
 *
 * @param <K> Key type.
 * @param <V> Object (values) type.
 */
public class FunctionalMap<K, V> implements Map<K, V>, SubMap<K, V> {
    /** Map which contain the data. */
    protected final Map<K, V> sourceMap;
    /** To convert an OlingoExpressionTree to an ExecutableExpressionTree. */
    protected final FunctionalVisitor transliterator;

    /**
     * Creates a FunctionalMap from the given datasource and translierator.
     * @param source data source.
     * @param visitor transliterator.
     */
    public FunctionalMap(Map<K, V> source, FunctionalVisitor visitor) {
        Objects.requireNonNull(source);
        Objects.requireNonNull(visitor);
        sourceMap = source;
        transliterator = visitor;
    }

    /// vvvv SubMap internface. vvvv

    @Override
    public SubMapBuilder<K, V> getSubMapBuilder() {
        return new SubMapBuilder<K, V>() {

            @Override
            public Map<K, V> build() {
                // Creates an ExecutableExpressionTree from `filter`
                ExecutableExpressionTree eet;
                if (filter != null) {
                    try {
                        eet = ExecutableExpressionTree.class.cast(filter.accept(transliterator));
                    } catch (ExceptionVisitExpression | ODataApplicationException ex) {
                        throw new RuntimeException(ex);
                    }
                } else {
                    eet = new ExecutableExpressionTree(ExecutableExpressionTree.Node
                            .createLeave(ConstantFactory.constantFactory(Boolean.TRUE)));
                }

                Map<K, V> new_source = new HashMap<>();

                // Builds a new map from entries validated by the `eet`
                for (Entry<K, V> e : sourceMap.entrySet()) {
                    if ((boolean) eet.exec(e.getValue())) {
                        if (skip > 0) {
                            skip--;
                        } else {
                            new_source.put(e.getKey(), e.getValue());
                            if (top > 0) {
                                top--;
                                if (top == 0) {
                                    break;
                                }
                            }
                        }
                    }
                }

                if (this.orderBy != null) {
                    Comparator cmp;
                    try {
                        cmp = Comparator.class.cast(orderBy.accept(transliterator));
                    } catch (ExceptionVisitExpression | ODataApplicationException ex) {
                        throw new RuntimeException(ex);
                    }
                    new_source = new SortedMap<>(new_source, cmp);
                }

                return new_source;
            }
        };
    }

    /// vvvv Map interface. vvvv

    @Override
    public int size() {
        return sourceMap.size();
    }

    @Override
    public boolean isEmpty() {
        return sourceMap.isEmpty();
    }

    @Override
    public boolean containsKey(Object key) {
        return sourceMap.containsKey(key);
    }

    @Override
    public V get(Object key) {
        return sourceMap.get(key);
    }

    @Override
    public Collection<V> values() {
        return Collections.unmodifiableCollection(sourceMap.values());
    }

    @Override
    public Set<K> keySet() {
        return Collections.unmodifiableSet(sourceMap.keySet());
    }

    @Override
    public Set<Map.Entry<K, V>> entrySet() {
        return Collections.unmodifiableSet(sourceMap.entrySet());
    }

    /// ^^^^   Implemented.   ^^^^
    /// vvvv Not implemented. vvvv

    @Override
    public V put(K key, V value) {
        throw new UnsupportedOperationException("Read-Only");
    }

    @Override
    public boolean containsValue(Object value) {
        throw new UnsupportedOperationException("Don't use");
    }

    @Override
    public V remove(Object key) {
        throw new UnsupportedOperationException("Read-Only");
    }

    @Override
    public void putAll(Map<? extends K, ? extends V> m) {
        throw new UnsupportedOperationException("Read-Only");
    }

    @Override
    public void clear() {
        throw new UnsupportedOperationException("Read-Only");
    }
}